1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

JSONColumns and XMLColumns revisited. They can retrieve their parameters directly

from the PTOS argument. For this to work, finding the table options is now split
in HA_CONNECT functions and exported functions available from out of ha_connect.
  modified:   storage/connect/ha_connect.cc
  modified:   storage/connect/libdoc.cpp
  modified:   storage/connect/mycat.h
  modified:   storage/connect/plgdbsem.h
  modified:   storage/connect/tabjson.cpp
  modified:   storage/connect/tabjson.h
  modified:   storage/connect/tabxml.cpp
  modified:   storage/connect/tabxml.h

The BIN table formats have been changed to handle the case of floating point values
when used with Big Endian or Little Endian machines.
  modified:   storage/connect/ha_connect.cc
  modified:   storage/connect/mysql-test/connect/r/bin.result
  modified:   storage/connect/mysql-test/connect/t/bin.test
  modified:   storage/connect/reldef.cpp
  modified:   storage/connect/tabdos.cpp
  modified:   storage/connect/tabdos.h
  modified:   storage/connect/tabfix.cpp
  modified:   storage/connect/tabfix.
h
This commit is contained in:
Olivier Bertrand
2015-05-26 01:02:33 +02:00
parent 37840d5313
commit fb98632930
15 changed files with 365 additions and 288 deletions

View File

@@ -195,9 +195,8 @@ extern "C" {
/***********************************************************************/ /***********************************************************************/
PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info); PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info);
PQRYRES VirColumns(PGLOBAL g, bool info); PQRYRES VirColumns(PGLOBAL g, bool info);
PQRYRES JSONColumns(PGLOBAL g, char *dp, const char *fn, char *objn, PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info);
int pretty, int lvl, int mxr, bool info); PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info);
PQRYRES XMLColumns(PGLOBAL g, char *dp, char *tab, PTOS topt, bool info);
void PushWarning(PGLOBAL g, THD *thd, int level); void PushWarning(PGLOBAL g, THD *thd, int level);
bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host, bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host,
const char *db, char *tab, const char *src, int port); const char *db, char *tab, const char *src, int port);
@@ -1017,6 +1016,117 @@ char *GetListOption(PGLOBAL g, const char *opname,
return opval; return opval;
} // end of GetListOption } // end of GetListOption
/****************************************************************************/
/* Return the value of a string option or NULL if not specified. */
/****************************************************************************/
char *GetStringTableOption(PGLOBAL g, PTOS options, char *opname, char *sdef)
{
const char *opval= NULL;
if (!options)
return sdef;
else if (!stricmp(opname, "Type"))
opval= options->type;
else if (!stricmp(opname, "Filename"))
opval= options->filename;
else if (!stricmp(opname, "Optname"))
opval= options->optname;
else if (!stricmp(opname, "Tabname"))
opval= options->tabname;
else if (!stricmp(opname, "Tablist"))
opval= options->tablist;
else if (!stricmp(opname, "Database") ||
!stricmp(opname, "DBname"))
opval= options->dbname;
else if (!stricmp(opname, "Separator"))
opval= options->separator;
else if (!stricmp(opname, "Qchar"))
opval= options->qchar;
else if (!stricmp(opname, "Module"))
opval= options->module;
else if (!stricmp(opname, "Subtype"))
opval= options->subtype;
else if (!stricmp(opname, "Catfunc"))
opval= options->catfunc;
else if (!stricmp(opname, "Srcdef"))
opval= options->srcdef;
else if (!stricmp(opname, "Colist"))
opval= options->colist;
else if (!stricmp(opname, "Data_charset"))
opval= options->data_charset;
if (!opval && options && options->oplist)
opval= GetListOption(g, opname, options->oplist);
return opval ? (char*)opval : sdef;
} // end of GetStringTableOption
/****************************************************************************/
/* Return the value of a Boolean option or bdef if not specified. */
/****************************************************************************/
bool GetBooleanTableOption(PGLOBAL g, PTOS options, char *opname, bool bdef)
{
bool opval= bdef;
char *pv;
if (!options)
return bdef;
else if (!stricmp(opname, "Mapped"))
opval= options->mapped;
else if (!stricmp(opname, "Huge"))
opval= options->huge;
else if (!stricmp(opname, "Split"))
opval= options->split;
else if (!stricmp(opname, "Readonly"))
opval= options->readonly;
else if (!stricmp(opname, "SepIndex"))
opval= options->sepindex;
else if (!stricmp(opname, "Header"))
opval= (options->header != 0); // Is Boolean for some table types
else if (options->oplist)
if ((pv= GetListOption(g, opname, options->oplist)))
opval= (!*pv || *pv == 'y' || *pv == 'Y' || atoi(pv) != 0);
return opval;
} // end of GetBooleanTableOption
/****************************************************************************/
/* Return the value of an integer option or NO_IVAL if not specified. */
/****************************************************************************/
int GetIntegerTableOption(PGLOBAL g, PTOS options, char *opname, int idef)
{
ulonglong opval= NO_IVAL;
if (!options)
return idef;
else if (!stricmp(opname, "Lrecl"))
opval= options->lrecl;
else if (!stricmp(opname, "Elements"))
opval= options->elements;
else if (!stricmp(opname, "Multiple"))
opval= options->multiple;
else if (!stricmp(opname, "Header"))
opval= options->header;
else if (!stricmp(opname, "Quoted"))
opval= options->quoted;
else if (!stricmp(opname, "Ending"))
opval= options->ending;
else if (!stricmp(opname, "Compressed"))
opval= (options->compressed);
if (opval == NO_IVAL) {
char *pv;
if ((pv= GetListOption(g, opname, options->oplist)))
opval= CharToNumber(pv, strlen(pv), ULONGLONG_MAX, true);
else
return idef;
} // endif opval
return (int)opval;
} // end of GetIntegerTableOption
/****************************************************************************/ /****************************************************************************/
/* Return the table option structure. */ /* Return the table option structure. */
/****************************************************************************/ /****************************************************************************/
@@ -1035,9 +1145,6 @@ char *ha_connect::GetRealString(const char *s)
char *sv; char *sv;
if (IsPartitioned() && s) { if (IsPartitioned() && s) {
// sv= (char*)PlugSubAlloc(xp->g, NULL, strlen(s) + strlen(partname));
// With wrong string pattern, the size of the constructed string
// can be more than strlen(s) + strlen(partname)
sv= (char*)PlugSubAlloc(xp->g, NULL, 0); sv= (char*)PlugSubAlloc(xp->g, NULL, 0);
sprintf(sv, s, partname); sprintf(sv, s, partname);
PlugSubAlloc(xp->g, NULL, strlen(sv) + 1); PlugSubAlloc(xp->g, NULL, strlen(sv) + 1);
@@ -1048,7 +1155,7 @@ char *ha_connect::GetRealString(const char *s)
} // end of GetRealString } // end of GetRealString
/****************************************************************************/ /****************************************************************************/
/* Return the value of a string option or NULL if not specified. */ /* Return the value of a string option or sdef if not specified. */
/****************************************************************************/ /****************************************************************************/
char *ha_connect::GetStringOption(char *opname, char *sdef) char *ha_connect::GetStringOption(char *opname, char *sdef)
{ {
@@ -1066,37 +1173,6 @@ char *ha_connect::GetStringOption(char *opname, char *sdef)
opval= thd_query_string(table->in_use)->str; opval= thd_query_string(table->in_use)->str;
else if (!stricmp(opname, "Partname")) else if (!stricmp(opname, "Partname"))
opval= partname; opval= partname;
else if (!options)
;
else if (!stricmp(opname, "Type"))
opval= (char*)options->type;
else if (!stricmp(opname, "Filename"))
opval= GetRealString(options->filename);
else if (!stricmp(opname, "Optname"))
opval= (char*)options->optname;
else if (!stricmp(opname, "Tabname"))
opval= GetRealString(options->tabname);
else if (!stricmp(opname, "Tablist"))
opval= (char*)options->tablist;
else if (!stricmp(opname, "Database") ||
!stricmp(opname, "DBname"))
opval= (char*)options->dbname;
else if (!stricmp(opname, "Separator"))
opval= (char*)options->separator;
else if (!stricmp(opname, "Qchar"))
opval= (char*)options->qchar;
else if (!stricmp(opname, "Module"))
opval= (char*)options->module;
else if (!stricmp(opname, "Subtype"))
opval= (char*)options->subtype;
else if (!stricmp(opname, "Catfunc"))
opval= (char*)options->catfunc;
else if (!stricmp(opname, "Srcdef"))
opval= (char*)options->srcdef;
else if (!stricmp(opname, "Colist"))
opval= (char*)options->colist;
else if (!stricmp(opname, "Data_charset"))
opval= (char*)options->data_charset;
else if (!stricmp(opname, "Table_charset")) { else if (!stricmp(opname, "Table_charset")) {
const CHARSET_INFO *chif= (tshp) ? tshp->table_charset const CHARSET_INFO *chif= (tshp) ? tshp->table_charset
: table->s->table_charset; : table->s->table_charset;
@@ -1104,17 +1180,13 @@ char *ha_connect::GetStringOption(char *opname, char *sdef)
if (chif) if (chif)
opval= (char*)chif->csname; opval= (char*)chif->csname;
} // endif Table_charset } else
opval= GetStringTableOption(xp->g, options, opname, NULL);
if (!opval && options && options->oplist) { if (opval && (!stricmp(opname, "connect")
opval= GetListOption(xp->g, opname, options->oplist); || !stricmp(opname, "tabname")
|| !stricmp(opname, "filename")))
if (opval && (!stricmp(opname, "connect") opval = GetRealString(opval);
|| !stricmp(opname, "tabname")
|| !stricmp(opname, "filename")))
opval = GetRealString(opval);
} // endif opval
if (!opval) { if (!opval) {
if (sdef && !strcmp(sdef, "*")) { if (sdef && !strcmp(sdef, "*")) {
@@ -1145,31 +1217,13 @@ char *ha_connect::GetStringOption(char *opname, char *sdef)
/****************************************************************************/ /****************************************************************************/
bool ha_connect::GetBooleanOption(char *opname, bool bdef) bool ha_connect::GetBooleanOption(char *opname, bool bdef)
{ {
bool opval= bdef; bool opval;
char *pv;
PTOS options= GetTableOptionStruct(); PTOS options= GetTableOptionStruct();
if (!stricmp(opname, "View")) if (!stricmp(opname, "View"))
opval= (tshp) ? tshp->is_view : table_share->is_view; opval= (tshp) ? tshp->is_view : table_share->is_view;
else if (!options) else
; opval= GetBooleanTableOption(xp->g, options, opname, bdef);
else if (!stricmp(opname, "Mapped"))
opval= options->mapped;
else if (!stricmp(opname, "Huge"))
opval= options->huge;
//else if (!stricmp(opname, "Compressed"))
// opval= options->compressed;
else if (!stricmp(opname, "Split"))
opval= options->split;
else if (!stricmp(opname, "Readonly"))
opval= options->readonly;
else if (!stricmp(opname, "SepIndex"))
opval= options->sepindex;
else if (!stricmp(opname, "Header"))
opval= (options->header != 0); // Is Boolean for some table types
else if (options->oplist)
if ((pv= GetListOption(xp->g, opname, options->oplist)))
opval= (!*pv || *pv == 'y' || *pv == 'Y' || atoi(pv) != 0);
return opval; return opval;
} // end of GetBooleanOption } // end of GetBooleanOption
@@ -1198,37 +1252,18 @@ bool ha_connect::SetBooleanOption(char *opname, bool b)
/****************************************************************************/ /****************************************************************************/
int ha_connect::GetIntegerOption(char *opname) int ha_connect::GetIntegerOption(char *opname)
{ {
ulonglong opval= NO_IVAL; int opval;
char *pv;
PTOS options= GetTableOptionStruct(); PTOS options= GetTableOptionStruct();
TABLE_SHARE *tsp= (tshp) ? tshp : table_share; TABLE_SHARE *tsp= (tshp) ? tshp : table_share;
if (!stricmp(opname, "Avglen")) if (!stricmp(opname, "Avglen"))
opval= (ulonglong)tsp->avg_row_length; opval= (int)tsp->avg_row_length;
else if (!stricmp(opname, "Estimate")) else if (!stricmp(opname, "Estimate"))
opval= (ulonglong)tsp->max_rows; opval= (int)tsp->max_rows;
else if (!options) else
; opval= GetIntegerTableOption(xp->g, options, opname, NO_IVAL);
else if (!stricmp(opname, "Lrecl"))
opval= options->lrecl;
else if (!stricmp(opname, "Elements"))
opval= options->elements;
else if (!stricmp(opname, "Multiple"))
opval= options->multiple;
else if (!stricmp(opname, "Header"))
opval= options->header;
else if (!stricmp(opname, "Quoted"))
opval= options->quoted;
else if (!stricmp(opname, "Ending"))
opval= options->ending;
else if (!stricmp(opname, "Compressed"))
opval= (options->compressed);
if (opval == (ulonglong)NO_IVAL && options && options->oplist) return opval;
if ((pv= GetListOption(xp->g, opname, options->oplist)))
opval= CharToNumber(pv, strlen(pv), ULONGLONG_MAX, true);
return (int)opval;
} // end of GetIntegerOption } // end of GetIntegerOption
/****************************************************************************/ /****************************************************************************/
@@ -4965,12 +5000,12 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
const char *fncn= "?"; const char *fncn= "?";
const char *user, *fn, *db, *host, *pwd, *sep, *tbl, *src; const char *user, *fn, *db, *host, *pwd, *sep, *tbl, *src;
const char *col, *ocl, *rnk, *pic, *fcl, *skc; const char *col, *ocl, *rnk, *pic, *fcl, *skc;
char *tab, *dsn, *shm, *dpath, *objn; char *tab, *dsn, *shm, *dpath;
#if defined(WIN32) #if defined(WIN32)
char *nsp= NULL, *cls= NULL; char *nsp= NULL, *cls= NULL;
#endif // WIN32 #endif // WIN32
int port= 0, hdr= 0, mxr= 0, mxe= 0, rc= 0, lvl= 0; int port= 0, hdr= 0, mxr= 0, mxe= 0, rc= 0;
int cop __attribute__((unused))= 0, pty= 2, lrecl= 0; int cop __attribute__((unused))= 0, lrecl= 0;
#if defined(ODBC_SUPPORT) #if defined(ODBC_SUPPORT)
POPARM sop = NULL; POPARM sop = NULL;
char *ucnc = NULL; char *ucnc = NULL;
@@ -5000,7 +5035,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
if (!g) if (!g)
return HA_ERR_INTERNAL_ERROR; return HA_ERR_INTERNAL_ERROR;
user= host= pwd= tbl= src= col= ocl= pic= fcl= skc= rnk= dsn= objn= NULL; user= host= pwd= tbl= src= col= ocl= pic= fcl= skc= rnk= dsn= NULL;
// Get the useful create options // Get the useful create options
ttp= GetTypeID(topt->type); ttp= GetTypeID(topt->type);
@@ -5031,7 +5066,6 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
skc= GetListOption(g, "skipcol", topt->oplist, NULL); skc= GetListOption(g, "skipcol", topt->oplist, NULL);
rnk= GetListOption(g, "rankcol", topt->oplist, NULL); rnk= GetListOption(g, "rankcol", topt->oplist, NULL);
pwd= GetListOption(g, "password", topt->oplist); pwd= GetListOption(g, "password", topt->oplist);
objn= GetListOption(g, "Object", topt->oplist, NULL);
#if defined(WIN32) #if defined(WIN32)
nsp= GetListOption(g, "namespace", topt->oplist); nsp= GetListOption(g, "namespace", topt->oplist);
cls= GetListOption(g, "class", topt->oplist); cls= GetListOption(g, "class", topt->oplist);
@@ -5049,8 +5083,6 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
#if defined(PROMPT_OK) #if defined(PROMPT_OK)
cop= atoi(GetListOption(g, "checkdsn", topt->oplist, "0")); cop= atoi(GetListOption(g, "checkdsn", topt->oplist, "0"));
#endif // PROMPT_OK #endif // PROMPT_OK
pty= atoi(GetListOption(g,"Pretty", topt->oplist, "2"));
lvl= atoi(GetListOption(g,"Level", topt->oplist, "0"));
} else { } else {
host= "localhost"; host= "localhost";
user= (ttp == TAB_ODBC ? NULL : "root"); user= (ttp == TAB_ODBC ? NULL : "root");
@@ -5342,7 +5374,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
qrp= VirColumns(g, fnc == FNC_COL); qrp= VirColumns(g, fnc == FNC_COL);
break; break;
case TAB_JSON: case TAB_JSON:
qrp= JSONColumns(g, (char*)db, fn, objn, pty, lrecl, lvl, fnc == FNC_COL); qrp= JSONColumns(g, (char*)db, topt, fnc == FNC_COL);
break; break;
#if defined(LIBXML2_SUPPORT) || defined(DOMDOC_SUPPORT) #if defined(LIBXML2_SUPPORT) || defined(DOMDOC_SUPPORT)
case TAB_XML: case TAB_XML:
@@ -6608,7 +6640,7 @@ maria_declare_plugin(connect)
0x0103, /* version number (1.03) */ 0x0103, /* version number (1.03) */
NULL, /* status variables */ NULL, /* status variables */
connect_system_variables, /* system variables */ connect_system_variables, /* system variables */
"1.03.0006", /* string version */ "1.03.0007", /* string version */
MariaDB_PLUGIN_MATURITY_BETA /* maturity */ MariaDB_PLUGIN_MATURITY_BETA /* maturity */
} }
maria_declare_plugin_end; maria_declare_plugin_end;

View File

@@ -533,8 +533,8 @@ int LIBXMLDOC::DumpDoc(PGLOBAL g, char *ofn)
// This function does not crash ( // This function does not crash (
if (xmlSaveFormatFileEnc((const char *)ofn, Docp, Encoding, 0) < 0) { if (xmlSaveFormatFileEnc((const char *)ofn, Docp, Encoding, 0) < 0) {
xmlErrorPtr err = xmlGetLastError(); xmlErrorPtr err = xmlGetLastError();
strcpy(g->Message, (err) ? err->message : "Error saving XML doc"); strcpy(g->Message, (err) ? err->message : "Error saving XML doc");
xmlResetError(Xerr);
rc = -1; rc = -1;
} // endif Save } // endif Save
// rc = xmlDocDump(of, Docp); // rc = xmlDocDump(of, Docp);
@@ -569,6 +569,7 @@ void LIBXMLDOC::CloseDoc(PGLOBAL g, PFBLOCK xp)
htrc("CloseDoc: xp=%p count=%d\n", xp, (xp) ? xp->Count : 0); htrc("CloseDoc: xp=%p count=%d\n", xp, (xp) ? xp->Count : 0);
//if (xp && xp->Count == 1) { //if (xp && xp->Count == 1) {
if (xp) {
if (Nlist) { if (Nlist) {
xmlXPathFreeNodeSet(Nlist); xmlXPathFreeNodeSet(Nlist);
@@ -605,7 +606,7 @@ void LIBXMLDOC::CloseDoc(PGLOBAL g, PFBLOCK xp)
Ctxp = NULL; Ctxp = NULL;
} // endif Ctxp } // endif Ctxp
// } // endif Count } // endif xp
CloseXML2File(g, xp, false); CloseXML2File(g, xp, false);
} // end of Close } // end of Close

View File

@@ -24,7 +24,7 @@
#include "block.h" #include "block.h"
#include "catalog.h" #include "catalog.h"
typedef struct ha_table_option_struct TOS, *PTOS; //typedef struct ha_table_option_struct TOS, *PTOS;
/** /**
structure for CREATE TABLE options (table options) structure for CREATE TABLE options (table options)

View File

@@ -15,11 +15,11 @@ CREATE TABLE t1
( (
fig INT(4) NOT NULL FIELD_FORMAT='C', fig INT(4) NOT NULL FIELD_FORMAT='C',
name CHAR(10) NOT NULL, name CHAR(10) NOT NULL,
birth DATE NOT NULL FIELD_FORMAT='L', birth DATE NOT NULL,
id CHAR(5) NOT NULL FIELD_FORMAT='L2', id CHAR(5) NOT NULL FIELD_FORMAT='S',
salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F', salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F',
dept INT(4) NOT NULL FIELD_FORMAT='L2' dept INT(4) NOT NULL FIELD_FORMAT='S'
) ENGINE=CONNECT TABLE_TYPE=BIN BLOCK_SIZE=5 FILE_NAME='Testbal.dat'; ) ENGINE=CONNECT TABLE_TYPE=BIN BLOCK_SIZE=5 FILE_NAME='Testbal.dat' OPTION_LIST='Endian=Little';
SELECT * FROM t1; SELECT * FROM t1;
fig name birth id salary dept fig name birth id salary dept
5500 ARCHIBALD 1980-01-25 3789 4380.50 318 5500 ARCHIBALD 1980-01-25 3789 4380.50 318
@@ -42,11 +42,11 @@ CREATE TABLE t1
( (
fig INT(4) NOT NULL FIELD_FORMAT='C', fig INT(4) NOT NULL FIELD_FORMAT='C',
name CHAR(10) NOT NULL, name CHAR(10) NOT NULL,
birth DATE NOT NULL FIELD_FORMAT='L', birth DATE NOT NULL,
id CHAR(5) NOT NULL FIELD_FORMAT='L2', id CHAR(5) NOT NULL FIELD_FORMAT='S',
salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F', salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F',
dept INT(4) NOT NULL FIELD_FORMAT='L2' dept INT(4) NOT NULL FIELD_FORMAT='S'
) ENGINE=CONNECT TABLE_TYPE=BIN READONLY=Yes FILE_NAME='Testbal.dat'; ) ENGINE=CONNECT TABLE_TYPE=BIN READONLY=Yes FILE_NAME='Testbal.dat' OPTION_LIST='Endian=Little';
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777); INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
ERROR HY000: Table 't1' is read only ERROR HY000: Table 't1' is read only
ALTER TABLE t1 READONLY=NO; ALTER TABLE t1 READONLY=NO;
@@ -55,11 +55,11 @@ Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`fig` int(4) NOT NULL `FIELD_FORMAT`='C', `fig` int(4) NOT NULL `FIELD_FORMAT`='C',
`name` char(10) NOT NULL, `name` char(10) NOT NULL,
`birth` date NOT NULL `FIELD_FORMAT`='L', `birth` date NOT NULL,
`id` char(5) NOT NULL `FIELD_FORMAT`='L2', `id` char(5) NOT NULL `FIELD_FORMAT`='S',
`salary` double(9,2) NOT NULL DEFAULT '0.00' `FIELD_FORMAT`='F', `salary` double(9,2) NOT NULL DEFAULT '0.00' `FIELD_FORMAT`='F',
`dept` int(4) NOT NULL `FIELD_FORMAT`='L2' `dept` int(4) NOT NULL `FIELD_FORMAT`='S'
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=BIN `FILE_NAME`='Testbal.dat' `READONLY`=NO ) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=BIN `FILE_NAME`='Testbal.dat' `OPTION_LIST`='Endian=Little' `READONLY`=NO
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777); INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
SELECT * FROM t1; SELECT * FROM t1;
fig name birth id salary dept fig name birth id salary dept
@@ -74,11 +74,11 @@ Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`fig` int(4) NOT NULL `FIELD_FORMAT`='C', `fig` int(4) NOT NULL `FIELD_FORMAT`='C',
`name` char(10) NOT NULL, `name` char(10) NOT NULL,
`birth` date NOT NULL `FIELD_FORMAT`='L', `birth` date NOT NULL,
`id` char(5) NOT NULL `FIELD_FORMAT`='L2', `id` char(5) NOT NULL `FIELD_FORMAT`='S',
`salary` double(9,2) NOT NULL DEFAULT '0.00' `FIELD_FORMAT`='F', `salary` double(9,2) NOT NULL DEFAULT '0.00' `FIELD_FORMAT`='F',
`dept` int(4) NOT NULL `FIELD_FORMAT`='L2' `dept` int(4) NOT NULL `FIELD_FORMAT`='S'
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=BIN `FILE_NAME`='Testbal.dat' `READONLY`=YES ) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=BIN `FILE_NAME`='Testbal.dat' `OPTION_LIST`='Endian=Little' `READONLY`=YES
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777); INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
ERROR HY000: Table 't1' is read only ERROR HY000: Table 't1' is read only
DROP TABLE t1; DROP TABLE t1;

View File

@@ -20,11 +20,11 @@ CREATE TABLE t1
( (
fig INT(4) NOT NULL FIELD_FORMAT='C', fig INT(4) NOT NULL FIELD_FORMAT='C',
name CHAR(10) NOT NULL, name CHAR(10) NOT NULL,
birth DATE NOT NULL FIELD_FORMAT='L', birth DATE NOT NULL,
id CHAR(5) NOT NULL FIELD_FORMAT='L2', id CHAR(5) NOT NULL FIELD_FORMAT='S',
salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F', salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F',
dept INT(4) NOT NULL FIELD_FORMAT='L2' dept INT(4) NOT NULL FIELD_FORMAT='S'
) ENGINE=CONNECT TABLE_TYPE=BIN BLOCK_SIZE=5 FILE_NAME='Testbal.dat'; ) ENGINE=CONNECT TABLE_TYPE=BIN BLOCK_SIZE=5 FILE_NAME='Testbal.dat' OPTION_LIST='Endian=Little';
SELECT * FROM t1; SELECT * FROM t1;
--error ER_GET_ERRMSG --error ER_GET_ERRMSG
@@ -41,11 +41,11 @@ CREATE TABLE t1
( (
fig INT(4) NOT NULL FIELD_FORMAT='C', fig INT(4) NOT NULL FIELD_FORMAT='C',
name CHAR(10) NOT NULL, name CHAR(10) NOT NULL,
birth DATE NOT NULL FIELD_FORMAT='L', birth DATE NOT NULL,
id CHAR(5) NOT NULL FIELD_FORMAT='L2', id CHAR(5) NOT NULL FIELD_FORMAT='S',
salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F', salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F',
dept INT(4) NOT NULL FIELD_FORMAT='L2' dept INT(4) NOT NULL FIELD_FORMAT='S'
) ENGINE=CONNECT TABLE_TYPE=BIN READONLY=Yes FILE_NAME='Testbal.dat'; ) ENGINE=CONNECT TABLE_TYPE=BIN READONLY=Yes FILE_NAME='Testbal.dat' OPTION_LIST='Endian=Little';
--error ER_OPEN_AS_READONLY --error ER_OPEN_AS_READONLY
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777); INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
ALTER TABLE t1 READONLY=NO; ALTER TABLE t1 READONLY=NO;

View File

@@ -389,6 +389,7 @@ typedef struct _qryres *PQRYRES;
typedef struct _colres *PCOLRES; typedef struct _colres *PCOLRES;
typedef struct _datpar *PDTP; typedef struct _datpar *PDTP;
typedef struct indx_used *PXUSED; typedef struct indx_used *PXUSED;
typedef struct ha_table_option_struct TOS, *PTOS;
/***********************************************************************/ /***********************************************************************/
/* Utility blocks for file and storage. */ /* Utility blocks for file and storage. */
@@ -593,6 +594,9 @@ DllExport void NewPointer(PTABS, void *, void *);
DllExport void SetTrc(void); DllExport void SetTrc(void);
DllExport char *GetListOption(PGLOBAL, const char *, const char *, DllExport char *GetListOption(PGLOBAL, const char *, const char *,
const char *def=NULL); const char *def=NULL);
DllExport char *GetStringTableOption(PGLOBAL, PTOS, char *, char *);
DllExport bool GetBooleanTableOption(PGLOBAL, PTOS, char *, bool);
DllExport int GetIntegerTableOption(PGLOBAL, PTOS, char *, int);
#define MSGID_NONE 0 #define MSGID_NONE 0
#define MSGID_CANNOT_OPEN 1 #define MSGID_CANNOT_OPEN 1

View File

@@ -247,7 +247,7 @@ bool TABDEF::Define(PGLOBAL g, PCATLG cat, LPCSTR name, LPCSTR am)
/***********************************************************************/ /***********************************************************************/
PSZ TABDEF::GetPath(void) PSZ TABDEF::GetPath(void)
{ {
return (Database) ? (PSZ)Database : Hc->GetDataPath(); return (Database) ? (PSZ)Database : (Hc) ? Hc->GetDataPath() : NULL;
} // end of GetPath } // end of GetPath
/***********************************************************************/ /***********************************************************************/
@@ -256,7 +256,8 @@ PSZ TABDEF::GetPath(void)
int TABDEF::GetColCatInfo(PGLOBAL g) int TABDEF::GetColCatInfo(PGLOBAL g)
{ {
char *type= GetStringCatInfo(g, "Type", "*"); char *type= GetStringCatInfo(g, "Type", "*");
int i, loff, poff, nof, nlg; char c, fty, eds;
int i, n, loff, poff, nof, nlg;
void *field= NULL; void *field= NULL;
TABTYPE tc; TABTYPE tc;
PCOLDEF cdp, lcdp= NULL, tocols= NULL; PCOLDEF cdp, lcdp= NULL, tocols= NULL;
@@ -331,28 +332,52 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
cdp->SetOffset(0); // Not to have shift cdp->SetOffset(0); // Not to have shift
case TAB_BIN: case TAB_BIN:
// BIN/VEC are packed by default // BIN/VEC are packed by default
if (nof) if (nof) {
// Field width is the internal representation width // Field width is the internal representation width
// that can also depend on the column format // that can also depend on the column format
switch (cdp->Fmt ? *cdp->Fmt : cdp->Decode ? 'C' : 'X') { fty = cdp->Decode ? 'C' : 'X';
case 'X': nof= cdp->Clen; eds = 0;
case 'C': break; n = 0;
case 'R':
case 'F':
// case 'L':
case 'I': nof= 4; break;
case 'D': nof= 8; break;
case 'S': nof= 2; break;
case 'T': nof= 1; break;
default: /* New format */
for (nof= 0, i= 0; cdp->Fmt[i]; i++)
if (isdigit(cdp->Fmt[i]))
nof= (nof * 10 + (cdp->Fmt[i] - '0'));
if (!nof) if (cdp->Fmt && !cdp->Decode) {
for (i = 0; cdp->Fmt[i]; i++) {
c = toupper(cdp->Fmt[i]);
if (isdigit(c))
n = (n * 10 + (c - '0'));
else if (c == 'L' || c == 'B' || c == 'H')
eds = c;
else
fty = c;
} // endfor i
} // endif Fmt
if (n)
nof = n;
else switch (fty) {
case 'X':
if (eds && IsTypeChar(cdp->Buf_Type))
nof = sizeof(longlong);
else
nof= cdp->Clen; nof= cdp->Clen;
} // endswitch Fmt break;
case 'C': break;
case 'R':
case 'F': nof = sizeof(float); break;
case 'I': nof = sizeof(int); break;
case 'D': nof = sizeof(double); break;
case 'S': nof = sizeof(short); break;
case 'T': nof = sizeof(char); break;
case 'G': nof = sizeof(longlong); break;
default: /* Wrong format */
sprintf(g->Message, "Invalid format %c", fty);
return -1;
} // endswitch fty
} // endif nof
default: default:
break; break;

View File

@@ -112,6 +112,7 @@ DOSDEF::DOSDEF(void)
Maxerr = 0; Maxerr = 0;
ReadMode = 0; ReadMode = 0;
Ending = 0; Ending = 0;
Teds = 0;
} // end of DOSDEF constructor } // end of DOSDEF constructor
/***********************************************************************/ /***********************************************************************/
@@ -146,6 +147,7 @@ bool DOSDEF::DefineAM(PGLOBAL g, LPCSTR am, int)
Padded = GetBoolCatInfo("Padded", false); Padded = GetBoolCatInfo("Padded", false);
Blksize = GetIntCatInfo("Blksize", 0); Blksize = GetIntCatInfo("Blksize", 0);
Eof = (GetIntCatInfo("EOF", 0) != 0); Eof = (GetIntCatInfo("EOF", 0) != 0);
Teds = toupper(*GetStringCatInfo(g, "Endian", ""));
} else if (Recfm == RECFM_DBF) { } else if (Recfm == RECFM_DBF) {
Maxerr = GetIntCatInfo("Maxerr", 0); Maxerr = GetIntCatInfo("Maxerr", 0);
Accept = GetBoolCatInfo("Accept", false); Accept = GetBoolCatInfo("Accept", false);

View File

@@ -91,6 +91,7 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */
int Maxerr; /* Maximum number of bad records (DBF) */ int Maxerr; /* Maximum number of bad records (DBF) */
int ReadMode; /* Specific to DBF */ int ReadMode; /* Specific to DBF */
int Ending; /* Length of end of lines */ int Ending; /* Length of end of lines */
int Teds; /* Binary table default endian setting */
}; // end of DOSDEF }; // end of DOSDEF
/***********************************************************************/ /***********************************************************************/

View File

@@ -68,10 +68,12 @@ USETEMP UseTemp(void);
/***********************************************************************/ /***********************************************************************/
TDBFIX::TDBFIX(PDOSDEF tdp, PTXF txfp) : TDBDOS(tdp, txfp) TDBFIX::TDBFIX(PDOSDEF tdp, PTXF txfp) : TDBDOS(tdp, txfp)
{ {
Teds = tdp->Teds; // For BIN tables
} // end of TDBFIX standard constructor } // end of TDBFIX standard constructor
TDBFIX::TDBFIX(PGLOBAL g, PTDBFIX tdbp) : TDBDOS(g, tdbp) TDBFIX::TDBFIX(PGLOBAL g, PTDBFIX tdbp) : TDBDOS(g, tdbp)
{ {
Teds = tdbp->Teds;
} // end of TDBFIX copy constructor } // end of TDBFIX copy constructor
// Method // Method
@@ -374,42 +376,63 @@ int TDBFIX::WriteDB(PGLOBAL g)
BINCOL::BINCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PSZ am) BINCOL::BINCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PSZ am)
: DOSCOL(g, cdp, tp, cp, i, am) : DOSCOL(g, cdp, tp, cp, i, am)
{ {
char *fmt = cdp->GetFmt(); char c, *fmt = cdp->GetFmt();
Fmt = GetDomain() ? 'C' : 'X';
Buff = NULL; Buff = NULL;
Eds = ((PTDBFIX)tp)->Teds;
N = 0;
M = GetTypeSize(Buf_Type, sizeof(longlong)); M = GetTypeSize(Buf_Type, sizeof(longlong));
Lim = 0; Lim = 0;
if (fmt) { if (fmt) {
Fmt = 'H'; for (N = 0, i = 0; fmt[i]; i++) {
c = toupper(fmt[i]);
for (N = 0, i = 0; fmt[i]; i++) if (isdigit(c))
if (isdigit(fmt[i])) N = (N * 10 + (c - '0'));
N = (N * 10 + (fmt[i] - '0')); else if (c == 'L' || c == 'B' || c == 'H')
Eds = c;
else else
Fmt = toupper(fmt[i]); Fmt = c;
if (N == GetTypeSize(Buf_Type, -1) && (Fmt == 'H' || Fmt == Endian)) { } // endfor i
// New format is a no op
N = 0;
Fmt = 'X';
} else if (Fmt == 'L' || Fmt == 'B' || Fmt == 'H') {
// This is a new format
if (!N)
N = GetTypeSize(Buf_Type, Long);
if (Fmt == 'H') // M is the size of the source value
Fmt = Endian; switch (Fmt) {
case 'C': Eds = 0; break;
case 'X': break;
case 'S': M = sizeof(short); break;
case 'T': M = sizeof(char); break;
case 'I': M = sizeof(int); break;
case 'G': M = sizeof(longlong); break;
case 'R': // Real
case 'F': M = sizeof(float); break;
case 'D': M = sizeof(double); break;
default:
sprintf(g->Message, MSG(BAD_BIN_FMT), Fmt, Name);
longjmp(g->jumper[g->jump_level], 11);
} // endswitch Fmt
} else if (IsTypeChar(Buf_Type))
Eds = 0;
if (Eds) {
// This is a byte order specification
if (!N)
N = M;
if (Eds != 'L' && Eds != 'B')
Eds = Endian;
if (N != M || Eds != Endian || IsTypeChar(Buf_Type)) {
Buff = (char*)PlugSubAlloc(g, NULL, M); Buff = (char*)PlugSubAlloc(g, NULL, M);
memset(Buff, 0, M); memset(Buff, 0, M);
Lim = MY_MIN(N, M); Lim = MY_MIN(N, M);
} // endif Fmt } else
Eds = 0; // New format is a no op
} else { } // endif Eds
N = 0;
Fmt = GetDomain() ? 'C' : 'X';
} // endif fmt
} // end of BINCOL constructor } // end of BINCOL constructor
@@ -419,6 +442,7 @@ BINCOL::BINCOL(PGLOBAL g, PCOLDEF cdp, PTDB tp, PCOL cp, int i, PSZ am)
/***********************************************************************/ /***********************************************************************/
BINCOL::BINCOL(BINCOL *col1, PTDB tdbp) : DOSCOL(col1, tdbp) BINCOL::BINCOL(BINCOL *col1, PTDB tdbp) : DOSCOL(col1, tdbp)
{ {
Eds = col1->Eds;
Fmt = col1->Fmt; Fmt = col1->Fmt;
N = col1->N; N = col1->N;
M = col1->M; M = col1->M;
@@ -470,25 +494,27 @@ void BINCOL::ReadColumn(PGLOBAL g)
/*********************************************************************/ /*********************************************************************/
/* Set Value from the line field. */ /* Set Value from the line field. */
/*********************************************************************/ /*********************************************************************/
if (N) { if (Eds) {
for (int i = 0; i < Lim; i++) for (int i = 0; i < Lim; i++)
if (Fmt == 'B' && Endian == 'L') if (Eds == 'B' && Endian == 'L')
Buff[i] = p[N - i - 1]; Buff[i] = p[N - i - 1];
else if (Fmt == 'L' && Endian == 'B') else if (Eds == 'L' && Endian == 'B')
Buff[M - i - 1] = p[i]; Buff[M - i - 1] = p[i];
else if (Endian == 'B') else if (Endian == 'B')
Buff[M - i - 1] = p[N - i - 1]; Buff[M - i - 1] = p[N - i - 1];
else else
Buff[i] = p[i]; Buff[i] = p[i];
if (IsTypeChar(Buf_Type)) p = Buff;
Value->SetValue(*(longlong*)Buff); } // endif Eds
else
Value->SetBinValue(Buff);
} else switch (Fmt) { switch (Fmt) {
case 'X': // Standard not converted values case 'X': // Standard not converted values
Value->SetBinValue(p); if (Eds && IsTypeChar(Buf_Type))
Value->SetValue(*(longlong*)p);
else
Value->SetBinValue(p);
break; break;
case 'S': // Short integer case 'S': // Short integer
Value->SetValue(*(short*)p); Value->SetValue(*(short*)p);
@@ -496,12 +522,12 @@ void BINCOL::ReadColumn(PGLOBAL g)
case 'T': // Tiny integer case 'T': // Tiny integer
Value->SetValue(*p); Value->SetValue(*p);
break; break;
// case 'L': // Long Integer
// strcpy(g->Message, "Format L is deprecated, use I");
// longjmp(g->jumper[g->jump_level], 11);
case 'I': // Integer case 'I': // Integer
Value->SetValue(*(int*)p); Value->SetValue(*(int*)p);
break; break;
case 'G': // Large (great) integer
Value->SetValue(*(longlong*)p);
break;
case 'F': // Float case 'F': // Float
case 'R': // Real case 'R': // Real
Value->SetValue((double)*(float*)p); Value->SetValue((double)*(float*)p);
@@ -553,41 +579,23 @@ void BINCOL::WriteColumn(PGLOBAL g)
if (Value != To_Val) if (Value != To_Val)
Value->SetValue_pval(To_Val, false); // Convert the updated value Value->SetValue_pval(To_Val, false); // Convert the updated value
p = tdbp->To_Line + Deplac; p = (Eds) ? Buff : tdbp->To_Line + Deplac;
/*********************************************************************/ /*********************************************************************/
/* Check whether updating is Ok, meaning col value is not too long. */ /* Check whether updating is Ok, meaning col value is not too long. */
/* Updating will be done only during the second pass (Status=true) */ /* Updating will be done only during the second pass (Status=true) */
/* Conversion occurs if the external format Fmt is specified. */ /* Conversion occurs if the external format Fmt is specified. */
/*********************************************************************/ /*********************************************************************/
if (N) { switch (Fmt) {
if (IsTypeChar(Buf_Type))
*(longlong *)Buff = Value->GetBigintValue();
else if (Value->GetBinValue(Buff, M, Status)) {
sprintf(g->Message, MSG(BIN_F_TOO_LONG),
Name, Value->GetSize(), M);
longjmp(g->jumper[g->jump_level], 31);
} // endif Buff
if (Status)
for (int i = 0; i < Lim; i++)
if (Fmt == 'B' && Endian == 'L')
p[N - i - 1] = Buff[i];
else if (Fmt == 'L' && Endian == 'B')
p[i] = Buff[M - i - 1];
else if (Endian == 'B')
p[N - i - 1] = Buff[M - i - 1];
else
p[i] = Buff[i];
} else switch (Fmt) {
case 'X': case 'X':
// Standard not converted values // Standard not converted values
if (Value->GetBinValue(p, Long, Status)) { if (Eds && IsTypeChar(Buf_Type))
*(longlong *)p = Value->GetBigintValue();
else if (Value->GetBinValue(p, Long, Status)) {
sprintf(g->Message, MSG(BIN_F_TOO_LONG), sprintf(g->Message, MSG(BIN_F_TOO_LONG),
Name, Value->GetSize(), Long); Name, Value->GetSize(), Long);
longjmp(g->jumper[g->jump_level], 31); longjmp(g->jumper[g->jump_level], 31);
} // endif p } // endif p
break; break;
case 'S': // Short integer case 'S': // Short integer
@@ -610,9 +618,6 @@ void BINCOL::WriteColumn(PGLOBAL g)
*p = (char)n; *p = (char)n;
break; break;
case 'L': // Long Integer
strcpy(g->Message, "Format L is deprecated, use I");
longjmp(g->jumper[g->jump_level], 11);
case 'I': // Integer case 'I': // Integer
n = Value->GetBigintValue(); n = Value->GetBigintValue();
@@ -623,7 +628,7 @@ void BINCOL::WriteColumn(PGLOBAL g)
*(int *)p = Value->GetIntValue(); *(int *)p = Value->GetIntValue();
break; break;
case 'B': // Large (big) integer case 'G': // Large (great) integer
if (Status) if (Status)
*(longlong *)p = Value->GetBigintValue(); *(longlong *)p = Value->GetBigintValue();
@@ -657,6 +662,21 @@ void BINCOL::WriteColumn(PGLOBAL g)
longjmp(g->jumper[g->jump_level], 11); longjmp(g->jumper[g->jump_level], 11);
} // endswitch Fmt } // endswitch Fmt
if (Eds && Status) {
p = tdbp->To_Line + Deplac;
for (int i = 0; i < Lim; i++)
if (Eds == 'B' && Endian == 'L')
p[N - i - 1] = Buff[i];
else if (Eds == 'L' && Endian == 'B')
p[i] = Buff[M - i - 1];
else if (Endian == 'B')
p[N - i - 1] = Buff[M - i - 1];
else
p[i] = Buff[i];
} // endif Eds
} // end of WriteColumn } // end of WriteColumn
/* ------------------------ End of TabFix ---------------------------- */ /* ------------------------ End of TabFix ---------------------------- */

View File

@@ -53,7 +53,8 @@ class DllExport TDBFIX : public TDBDOS {
protected: protected:
virtual bool PrepareWriting(PGLOBAL g) {return false;} virtual bool PrepareWriting(PGLOBAL g) {return false;}
// Members are inherited from TDBDOS // Members
char Teds; /* Binary table default endian setting */
}; // end of class TDBFIX }; // end of class TDBFIX
/***********************************************************************/ /***********************************************************************/
@@ -86,7 +87,8 @@ class DllExport BINCOL : public DOSCOL {
// Members // Members
static char Endian; // The host endian setting (L or B) static char Endian; // The host endian setting (L or B)
char *Buff; // Utility buffer char *Buff; // Utility buffer
char Fmt; // The file endian setting or old format char Eds; // The file endian setting
char Fmt; // The converted value format
int N; // The number of bytes in the file int N; // The number of bytes in the file
int M; // The buffer type size int M; // The buffer type size
int Lim; // Min(N,M) int Lim; // Min(N,M)

View File

@@ -59,16 +59,15 @@ typedef struct _jncol {
/* JSONColumns: construct the result blocks containing the description */ /* JSONColumns: construct the result blocks containing the description */
/* of all the columns of a table contained inside a JSON file. */ /* of all the columns of a table contained inside a JSON file. */
/***********************************************************************/ /***********************************************************************/
PQRYRES JSONColumns(PGLOBAL g, char *dp, const char *fn, char *objn, PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info)
int pretty, int lrecl, int lvl, bool info)
{ {
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT, static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT,
TYPE_INT, TYPE_SHORT, TYPE_SHORT, TYPE_STRING}; TYPE_INT, TYPE_SHORT, TYPE_SHORT, TYPE_STRING};
static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC, static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC,
FLD_LENGTH, FLD_SCALE, FLD_NULL, FLD_FORMAT}; FLD_LENGTH, FLD_SCALE, FLD_NULL, FLD_FORMAT};
static unsigned int length[] = {0, 6, 8, 10, 10, 6, 6, 0}; static unsigned int length[] = {0, 6, 8, 10, 10, 6, 6, 0};
char filename[_MAX_PATH], colname[65], fmt[129]; char *fn, colname[65], fmt[129];
int i, j, n = 0; int i, j, lvl, n = 0;
int ncol = sizeof(buftyp) / sizeof(int); int ncol = sizeof(buftyp) / sizeof(int);
PVAL valp; PVAL valp;
JCOL jcol; JCOL jcol;
@@ -91,26 +90,29 @@ PQRYRES JSONColumns(PGLOBAL g, char *dp, const char *fn, char *objn,
goto skipit; goto skipit;
} // endif info } // endif info
if (trace)
htrc("File %s pretty=%d lvl=%d lrecl=%d\n",
SVP(fn), pretty, lvl, lrecl);
/*********************************************************************/ /*********************************************************************/
/* Open the input file. */ /* Open the input file. */
/*********************************************************************/ /*********************************************************************/
if (!fn) { if (!(fn = GetStringTableOption(g, topt, "Filename", NULL))) {
strcpy(g->Message, MSG(MISSING_FNAME)); strcpy(g->Message, MSG(MISSING_FNAME));
return NULL; return NULL;
} else } else {
PlugSetPath(filename, fn, dp); lvl = GetIntegerTableOption(g, topt, "Level", 0);
lvl = (lvl < 0) ? 0 : (lvl > 16) ? 16 : lvl;
} // endif fn
tdp = new(g) JSONDEF; tdp = new(g) JSONDEF;
tdp->Database = dp; tdp->Fn = fn;
tdp->Fn = filename; tdp->Database = SetPath(g, db);
tdp->Objname = objn; tdp->Objname = GetStringTableOption(g, topt, "Object", NULL);
tdp->Pretty = pretty; tdp->Base = GetIntegerTableOption(g, topt, "Base", 0) ? 1 : 0;
tdp->Pretty = GetIntegerTableOption(g, topt, "Pretty", 2);
if (pretty == 2) { if (trace)
htrc("File %s objname=%s pretty=%d lvl=%d\n",
tdp->Fn, tdp->Objname, tdp->Pretty, lvl);
if (tdp->Pretty == 2) {
tjsp = new(g) TDBJSON(tdp, new(g) MAPFAM(tdp)); tjsp = new(g) TDBJSON(tdp, new(g) MAPFAM(tdp));
if (tjsp->MakeDocument(g)) if (tjsp->MakeDocument(g))
@@ -118,13 +120,12 @@ PQRYRES JSONColumns(PGLOBAL g, char *dp, const char *fn, char *objn,
jsp = (tjsp->GetDoc()) ? tjsp->GetDoc()->GetValue(0) : NULL; jsp = (tjsp->GetDoc()) ? tjsp->GetDoc()->GetValue(0) : NULL;
} else { } else {
if (!lrecl) { if (!(tdp->Lrecl = GetIntegerTableOption(g, topt, "Lrecl", 0))) {
sprintf(g->Message, "LRECL must be specified for pretty=%d", pretty); sprintf(g->Message, "LRECL must be specified for pretty=%d", tdp->Pretty);
return NULL; return NULL;
} // endif lrecl } // endif lrecl
tdp->Lrecl = lrecl; tdp->Ending = GetIntegerTableOption(g, topt, "Ending", CRLF);
tdp->Ending = CRLF;
tjnp = new(g) TDBJSN(tdp, new(g) DOSFAM(tdp)); tjnp = new(g) TDBJSN(tdp, new(g) DOSFAM(tdp));
tjnp->SetMode(MODE_READ); tjnp->SetMode(MODE_READ);
@@ -265,7 +266,7 @@ PQRYRES JSONColumns(PGLOBAL g, char *dp, const char *fn, char *objn,
jcp->Found = false; jcp->Found = false;
} // endfor jcp } // endfor jcp
if (pretty != 2) { if (tdp->Pretty != 2) {
// Read next record // Read next record
switch (tjnp->ReadDB(g)) { switch (tjnp->ReadDB(g)) {
case RC_EF: case RC_EF:
@@ -285,7 +286,7 @@ PQRYRES JSONColumns(PGLOBAL g, char *dp, const char *fn, char *objn,
} // endor i } // endor i
if (pretty != 2) if (tdp->Pretty != 2)
tjnp->CloseDB(g); tjnp->CloseDB(g);
skipit: skipit:
@@ -341,7 +342,7 @@ PQRYRES JSONColumns(PGLOBAL g, char *dp, const char *fn, char *objn,
return qrp; return qrp;
err: err:
if (pretty != 2) if (tdp->Pretty != 2)
tjnp->CloseDB(g); tjnp->CloseDB(g);
return NULL; return NULL;
@@ -356,8 +357,7 @@ JSONDEF::JSONDEF(void)
Xcol = NULL; Xcol = NULL;
Pretty = 2; Pretty = 2;
Limit = 1; Limit = 1;
Level = 0; Base = 0;
ReadMode = 0;
Strict = false; Strict = false;
} // end of JSONDEF constructor } // end of JSONDEF constructor
@@ -370,9 +370,8 @@ bool JSONDEF::DefineAM(PGLOBAL g, LPCSTR, int poff)
Objname = GetStringCatInfo(g, "Object", NULL); Objname = GetStringCatInfo(g, "Object", NULL);
Xcol = GetStringCatInfo(g, "Expand", NULL); Xcol = GetStringCatInfo(g, "Expand", NULL);
Pretty = GetIntCatInfo("Pretty", 2); Pretty = GetIntCatInfo("Pretty", 2);
Level = GetIntCatInfo("Level", 0);
Limit = GetIntCatInfo("Limit", 10); Limit = GetIntCatInfo("Limit", 10);
Base = GetIntCatInfo("Base", 0); Base = GetIntCatInfo("Base", 0) ? 1 : 0;
return DOSDEF::DefineAM(g, "DOS", poff); return DOSDEF::DefineAM(g, "DOS", poff);
} // end of DefineAM } // end of DefineAM
@@ -1856,11 +1855,8 @@ void TDBJSON::CloseDB(PGLOBAL g)
/***********************************************************************/ /***********************************************************************/
TDBJCL::TDBJCL(PJDEF tdp) : TDBCAT(tdp) TDBJCL::TDBJCL(PJDEF tdp) : TDBCAT(tdp)
{ {
Fn = tdp->GetFn(); Topt = tdp->GetTopt();
Objn = tdp->Objname; Db = (char*)tdp->GetDB();
Pretty = tdp->Pretty;
Lrecl = tdp->Lrecl;
lvl = tdp->Level;
} // end of TDBJCL constructor } // end of TDBJCL constructor
/***********************************************************************/ /***********************************************************************/
@@ -1868,8 +1864,7 @@ TDBJCL::TDBJCL(PJDEF tdp) : TDBCAT(tdp)
/***********************************************************************/ /***********************************************************************/
PQRYRES TDBJCL::GetResult(PGLOBAL g) PQRYRES TDBJCL::GetResult(PGLOBAL g)
{ {
return JSONColumns(g, ((PTABDEF)To_Def)->GetPath(), Fn, Objn, return JSONColumns(g, Db, Topt, false);
Pretty, Lrecl, lvl, false);
} // end of GetResult } // end of GetResult
/* --------------------------- End of json --------------------------- */ /* --------------------------- End of json --------------------------- */

View File

@@ -36,8 +36,7 @@ class JSONDEF : public DOSDEF { /* Table description */
friend class TDBJSON; friend class TDBJSON;
friend class TDBJSN; friend class TDBJSN;
friend class TDBJCL; friend class TDBJCL;
friend PQRYRES JSONColumns(PGLOBAL, char *, const char *, char *, friend PQRYRES JSONColumns(PGLOBAL, char*, PTOS, bool);
int, int, int, bool);
public: public:
// Constructor // Constructor
JSONDEF(void); JSONDEF(void);
@@ -226,11 +225,6 @@ class TDBJCL : public TDBCAT {
virtual PQRYRES GetResult(PGLOBAL g); virtual PQRYRES GetResult(PGLOBAL g);
// Members // Members
//char *Dp; PTOS Topt;
const char *Fn; char *Db;
char *Objn;
int Pretty;
int Lrecl;
int lvl;
}; // end of class TDBJCL }; // end of class TDBJCL

View File

@@ -110,14 +110,14 @@ typedef struct LVL {
/* XMLColumns: construct the result blocks containing the description */ /* XMLColumns: construct the result blocks containing the description */
/* of all the columns of a table contained inside an XML file. */ /* of all the columns of a table contained inside an XML file. */
/***********************************************************************/ /***********************************************************************/
PQRYRES XMLColumns(PGLOBAL g, char *dp, char *tab, PTOS topt, bool info) PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info)
{ {
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT, static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT,
TYPE_INT, TYPE_SHORT, TYPE_SHORT, TYPE_STRING}; TYPE_INT, TYPE_SHORT, TYPE_SHORT, TYPE_STRING};
static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC, static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC,
FLD_LENGTH, FLD_SCALE, FLD_NULL, FLD_FORMAT}; FLD_LENGTH, FLD_SCALE, FLD_NULL, FLD_FORMAT};
static unsigned int length[] = {0, 6, 8, 10, 10, 6, 6, 0}; static unsigned int length[] = {0, 6, 8, 10, 10, 6, 6, 0};
char *op, colname[65], fmt[129], buf[512]; char *fn, *op, colname[65], fmt[129], buf[512];
int i, j, lvl, n = 0; int i, j, lvl, n = 0;
int ncol = sizeof(buftyp) / sizeof(int); int ncol = sizeof(buftyp) / sizeof(int);
bool ok = true; bool ok = true;
@@ -138,21 +138,23 @@ PQRYRES XMLColumns(PGLOBAL g, char *dp, char *tab, PTOS topt, bool info)
/*********************************************************************/ /*********************************************************************/
/* Open the input file. */ /* Open the input file. */
/*********************************************************************/ /*********************************************************************/
if (!topt->filename) { if (!(fn = GetStringTableOption(g, topt, "Filename", NULL))) {
strcpy(g->Message, MSG(MISSING_FNAME)); strcpy(g->Message, MSG(MISSING_FNAME));
return NULL; return NULL;
} else } else {
lvl = atoi(GetListOption(g, "Level", topt->oplist, "0")); lvl = GetIntegerTableOption(g, topt, "Level", 0);
lvl = (lvl < 0) ? 0 : (lvl > 16) ? 16 : lvl;
} // endif fn
if (trace) if (trace)
htrc("File %s lvl=%d\n", topt->filename, lvl); htrc("File %s lvl=%d\n", topt->filename, lvl);
tdp = new(g) XMLDEF; tdp = new(g) XMLDEF;
tdp->Database = dp; tdp->Fn = fn;
tdp->Fn = (char*)topt->filename; tdp->Database = SetPath(g, db);
tdp->Tabname = tab; tdp->Tabname = tab;
if (!(op = GetListOption(g, "Xmlsup", topt->oplist, NULL))) if (!(op = GetStringTableOption(g, topt, "Xmlsup", NULL)))
#if defined(WIN32) #if defined(WIN32)
tdp->Usedom = true; tdp->Usedom = true;
#else // !WIN32 #else // !WIN32
@@ -432,7 +434,7 @@ XMLDEF::XMLDEF(void)
/***********************************************************************/ /***********************************************************************/
bool XMLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) bool XMLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{ {
char *defrow, *defcol, buf[10]; char *defrow, *defcol, buf[10];
Fn = GetStringCatInfo(g, "Filename", NULL); Fn = GetStringCatInfo(g, "Filename", NULL);
Encoding = GetStringCatInfo(g, "Encoding", "UTF-8"); Encoding = GetStringCatInfo(g, "Encoding", "UTF-8");
@@ -447,7 +449,7 @@ bool XMLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
return true; return true;
} // endif flag } // endif flag
defrow = defcol = ""; defrow = defcol = NULL;
GetCharCatInfo("Coltype", "", buf, sizeof(buf)); GetCharCatInfo("Coltype", "", buf, sizeof(buf));
switch (toupper(*buf)) { switch (toupper(*buf)) {
@@ -480,12 +482,12 @@ bool XMLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Tabname = GetStringCatInfo(g, "Tabname", Tabname); Tabname = GetStringCatInfo(g, "Tabname", Tabname);
Rowname = GetStringCatInfo(g, "Rownode", defrow); Rowname = GetStringCatInfo(g, "Rownode", defrow);
Colname = GetStringCatInfo(g, "Colnode", defcol); Colname = GetStringCatInfo(g, "Colnode", defcol);
Mulnode = GetStringCatInfo(g, "Mulnode", ""); Mulnode = GetStringCatInfo(g, "Mulnode", NULL);
XmlDB = GetStringCatInfo(g, "XmlDB", ""); XmlDB = GetStringCatInfo(g, "XmlDB", NULL);
Nslist = GetStringCatInfo(g, "Nslist", ""); Nslist = GetStringCatInfo(g, "Nslist", NULL);
DefNs = GetStringCatInfo(g, "DefNs", ""); DefNs = GetStringCatInfo(g, "DefNs", NULL);
Limit = GetIntCatInfo("Limit", 10); Limit = GetIntCatInfo("Limit", 10);
Xpand = (GetIntCatInfo("Expand", 0) != 0); Xpand = GetBoolCatInfo("Expand", false);
Header = GetIntCatInfo("Header", 0); Header = GetIntCatInfo("Header", 0);
GetCharCatInfo("Xmlsup", "*", buf, sizeof(buf)); GetCharCatInfo("Xmlsup", "*", buf, sizeof(buf));
@@ -501,8 +503,8 @@ bool XMLDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Usedom = (toupper(*buf) == 'M' || toupper(*buf) == 'D'); Usedom = (toupper(*buf) == 'M' || toupper(*buf) == 'D');
// Get eventual table node attribute // Get eventual table node attribute
Attrib = GetStringCatInfo(g, "Attribute", ""); Attrib = GetStringCatInfo(g, "Attribute", NULL);
Hdattr = GetStringCatInfo(g, "HeadAttr", ""); Hdattr = GetStringCatInfo(g, "HeadAttr", NULL);
return false; return false;
} // end of DefineAM } // end of DefineAM
@@ -543,14 +545,14 @@ TDBXML::TDBXML(PXMLDEF tdp) : TDBASE(tdp)
Xfile = tdp->Fn; Xfile = tdp->Fn;
Enc = tdp->Encoding; Enc = tdp->Encoding;
Tabname = tdp->Tabname; Tabname = tdp->Tabname;
Rowname = (tdp->Rowname && *tdp->Rowname) ? tdp->Rowname : NULL; Rowname = (tdp->Rowname) ? tdp->Rowname : NULL;
Colname = (tdp->Colname && *tdp->Colname) ? tdp->Colname : NULL; Colname = (tdp->Colname) ? tdp->Colname : NULL;
Mulnode = (tdp->Mulnode && *tdp->Mulnode) ? tdp->Mulnode : NULL; Mulnode = (tdp->Mulnode) ? tdp->Mulnode : NULL;
XmlDB = (tdp->XmlDB && *tdp->XmlDB) ? tdp->XmlDB : NULL; XmlDB = (tdp->XmlDB) ? tdp->XmlDB : NULL;
Nslist = (tdp->Nslist && *tdp->Nslist) ? tdp->Nslist : NULL; Nslist = (tdp->Nslist) ? tdp->Nslist : NULL;
DefNs = (tdp->DefNs && *tdp->DefNs) ? tdp->DefNs : NULL; DefNs = (tdp->DefNs) ? tdp->DefNs : NULL;
Attrib = (tdp->Attrib && *tdp->Attrib) ? tdp->Attrib : NULL; Attrib = (tdp->Attrib) ? tdp->Attrib : NULL;
Hdattr = (tdp->Hdattr && *tdp->Hdattr) ? tdp->Hdattr : NULL; Hdattr = (tdp->Hdattr) ? tdp->Hdattr : NULL;
Coltype = tdp->Coltype; Coltype = tdp->Coltype;
Limit = tdp->Limit; Limit = tdp->Limit;
Xpand = tdp->Xpand; Xpand = tdp->Xpand;
@@ -1015,7 +1017,7 @@ int TDBXML::GetMaxSize(PGLOBAL g)
else else
MaxSize = 10; MaxSize = 10;
} // endif MaxSize } // endif MaxSize
return MaxSize; return MaxSize;
} // end of GetMaxSize } // end of GetMaxSize
@@ -1256,7 +1258,7 @@ void TDBXML::CloseDB(PGLOBAL g)
{ {
if (Docp) { if (Docp) {
if (Changed) { if (Changed) {
char filename[_MAX_PATH]; char filename[_MAX_PATH];
// We used the file name relative to recorded datapath // We used the file name relative to recorded datapath
PlugSetPath(filename, Xfile, GetPath()); PlugSetPath(filename, Xfile, GetPath());
@@ -1660,7 +1662,7 @@ void XMLCOL::WriteColumn(PGLOBAL g)
/*********************************************************************/ /*********************************************************************/
/* Null values are represented by no node. */ /* Null values are represented by no node. */
/*********************************************************************/ /*********************************************************************/
if (Value->IsNull()) if (Value->IsNull())
return; return;
/*********************************************************************/ /*********************************************************************/
@@ -2160,7 +2162,7 @@ void XPOSCOL::WriteColumn(PGLOBAL g)
TDBXCT::TDBXCT(PXMLDEF tdp) : TDBCAT(tdp) TDBXCT::TDBXCT(PXMLDEF tdp) : TDBCAT(tdp)
{ {
Topt = tdp->GetTopt(); Topt = tdp->GetTopt();
Dp = tdp->GetPath(); Db = (char*)tdp->GetDB();
Tabn = tdp->Tabname; Tabn = tdp->Tabname;
} // end of TDBXCT constructor } // end of TDBXCT constructor
@@ -2169,7 +2171,7 @@ TDBXCT::TDBXCT(PXMLDEF tdp) : TDBCAT(tdp)
/***********************************************************************/ /***********************************************************************/
PQRYRES TDBXCT::GetResult(PGLOBAL g) PQRYRES TDBXCT::GetResult(PGLOBAL g)
{ {
return XMLColumns(g, Dp, Tabn, Topt, false); return XMLColumns(g, Db, Tabn, Topt, false);
} // end of GetResult } // end of GetResult
/* ------------------------ End of Tabxml ---------------------------- */ /* ------------------------ End of Tabxml ---------------------------- */

View File

@@ -1,7 +1,7 @@
/*************** Tabxml H Declares Source Code File (.H) ***************/ /*************** Tabxml H Declares Source Code File (.H) ***************/
/* Name: TABXML.H Version 1.6 */ /* Name: TABXML.H Version 1.6 */
/* */ /* */
/* (C) Copyright to the author Olivier BERTRAND 2007-2013 */ /* (C) Copyright to the author Olivier BERTRAND 2007-2015 */
/* */ /* */
/* This file contains the XML table classes declares. */ /* This file contains the XML table classes declares. */
/***********************************************************************/ /***********************************************************************/
@@ -255,8 +255,7 @@ class TDBXCT : public TDBCAT {
// Members // Members
PTOS Topt; PTOS Topt;
char *Dp; char *Db;
//const char *Fn;
char *Tabn; char *Tabn;
}; // end of class TDBXCT }; // end of class TDBXCT