Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
56114a41
Commit
56114a41
authored
Feb 19, 2015
by
Sergei Golubchik
Browse files
Options
Browse Files
Download
Plain Diff
merge 10.0-connect
parents
174bccd3
d9175f38
Changes
34
Show whitespace changes
Inline
Side-by-side
Showing
34 changed files
with
2431 additions
and
1490 deletions
+2431
-1490
storage/connect/CMakeLists.txt
storage/connect/CMakeLists.txt
+3
-8
storage/connect/array.h
storage/connect/array.h
+1
-0
storage/connect/checklvl.h
storage/connect/checklvl.h
+7
-0
storage/connect/connect.cc
storage/connect/connect.cc
+4
-1
storage/connect/ha_connect.cc
storage/connect/ha_connect.cc
+172
-81
storage/connect/json.cpp
storage/connect/json.cpp
+1106
-1055
storage/connect/json.h
storage/connect/json.h
+14
-1
storage/connect/jsonudf.cpp
storage/connect/jsonudf.cpp
+494
-0
storage/connect/myconn.cpp
storage/connect/myconn.cpp
+3
-2
storage/connect/mysql-test/connect/r/json.result
storage/connect/mysql-test/connect/r/json.result
+32
-8
storage/connect/mysql-test/connect/t/json.test
storage/connect/mysql-test/connect/t/json.test
+2
-2
storage/connect/myutil.cpp
storage/connect/myutil.cpp
+12
-10
storage/connect/odbccat.h
storage/connect/odbccat.h
+11
-3
storage/connect/odbconn.cpp
storage/connect/odbconn.cpp
+51
-24
storage/connect/odbconn.h
storage/connect/odbconn.h
+11
-5
storage/connect/tabdos.h
storage/connect/tabdos.h
+1
-0
storage/connect/tabjson.cpp
storage/connect/tabjson.cpp
+330
-214
storage/connect/tabjson.h
storage/connect/tabjson.h
+13
-11
storage/connect/tabmysql.cpp
storage/connect/tabmysql.cpp
+6
-9
storage/connect/taboccur.cpp
storage/connect/taboccur.cpp
+1
-1
storage/connect/tabodbc.cpp
storage/connect/tabodbc.cpp
+64
-36
storage/connect/tabodbc.h
storage/connect/tabodbc.h
+8
-2
storage/connect/tabpivot.cpp
storage/connect/tabpivot.cpp
+3
-3
storage/connect/tabpivot.h
storage/connect/tabpivot.h
+2
-1
storage/connect/tabtbl.cpp
storage/connect/tabtbl.cpp
+8
-6
storage/connect/tabutil.cpp
storage/connect/tabutil.cpp
+22
-1
storage/connect/tabutil.h
storage/connect/tabutil.h
+8
-1
storage/connect/tabxcl.cpp
storage/connect/tabxcl.cpp
+1
-1
storage/connect/tabxcl.h
storage/connect/tabxcl.h
+1
-0
storage/connect/valblk.h
storage/connect/valblk.h
+6
-0
storage/connect/value.cpp
storage/connect/value.cpp
+7
-4
storage/connect/xindex.h
storage/connect/xindex.h
+1
-0
storage/connect/xobject.cpp
storage/connect/xobject.cpp
+25
-0
storage/connect/xobject.h
storage/connect/xobject.h
+1
-0
No files found.
storage/connect/CMakeLists.txt
View file @
56114a41
...
...
@@ -21,9 +21,9 @@ ha_connect.cc connect.cc user_connect.cc mycat.cc
fmdlex.c osutil.c plugutil.c rcmsg.c rcmsg.h
array.cpp blkfil.cpp colblk.cpp csort.cpp
filamap.cpp filamdbf.cpp filamfix.cpp filamtxt.cpp filamvct.cpp filamzip.cpp
filter.cpp json.cpp
maputil.cpp myutil.cpp plgdbutl.cpp reldef.cpp tabcol
.cpp
tab
dos.cpp tabfix.cpp tabfmt.cpp tabjson.cpp table.cpp tabmul.cpp taboccur
.cpp
tabpivot.cpp tabsys.cpp tabtbl.cpp tabutil.cpp tabvct.cpp tabvir.cpp
filter.cpp json.cpp
jsonudf.cpp maputil.cpp myutil.cpp plgdbutl.cpp reldef
.cpp
tab
col.cpp tabdos.cpp tabfix.cpp tabfmt.cpp tabjson.cpp table.cpp tabmul
.cpp
tab
occur.cpp tab
pivot.cpp tabsys.cpp tabtbl.cpp tabutil.cpp tabvct.cpp tabvir.cpp
tabxcl.cpp valblk.cpp value.cpp xindex.cpp xobject.cpp
array.h blkfil.h block.h catalog.h checklvl.h colblk.h connect.h csort.h
...
...
@@ -72,11 +72,6 @@ IF(UNIX)
message
(
STATUS
"CONNECT: GCC: Some warnings disabled"
)
endif
(
WITH_WARNINGS
)
# Avoid compilation failure in maintainer mode
IF
(
CMAKE_COMPILER_IS_GNUCXX
)
SET
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-Wno-overloaded-virtual -Wno-error=type-limits"
)
ENDIF
(
CMAKE_COMPILER_IS_GNUCXX
)
add_definitions
(
-DUNIX -DLINUX -DUBUNTU
)
SET
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-fpermissive -fexceptions -fPIC "
)
...
...
storage/connect/array.h
View file @
56114a41
...
...
@@ -50,6 +50,7 @@ class DllExport ARRAY : public XOBJECT, public CSORT { // Array descblock
// void SetCorrel(bool b) {Correlated = b;}
// Methods
using
XOBJECT
::
GetIntValue
;
virtual
void
Reset
(
void
)
{
Bot
=
-
1
;}
virtual
int
Qcompare
(
int
*
,
int
*
);
virtual
bool
Compare
(
PXOB
)
{
assert
(
FALSE
);
return
FALSE
;}
...
...
storage/connect/checklvl.h
View file @
56114a41
...
...
@@ -40,4 +40,11 @@ enum USETEMP {TMP_NO = 0, /* Never */
TMP_FORCE
=
3
,
/* Forced for MAP tables */
TMP_TEST
=
4
};
/* Testing value */
/***********************************************************************/
/* Following definitions indicate conversion of TEXT columns. */
/***********************************************************************/
enum
TYPCONV
{
TPC_NO
=
0
,
/* Never */
TPC_YES
=
1
,
/* Always */
TPC_SKIP
=
2
};
/* Skip TEXT columns */
#endif // _CHKLVL_DEFINED_
storage/connect/connect.cc
View file @
56114a41
...
...
@@ -469,9 +469,12 @@ RCODE CntReadNext(PGLOBAL g, PTDB tdbp)
}
while
(
rc
==
RC_NF
);
if
(
rc
==
RC_OK
)
rc
=
EvalColumns
(
g
,
tdbp
,
false
);
err:
g
->
jump_level
--
;
return
(
rc
!=
RC_OK
)
?
rc
:
EvalColumns
(
g
,
tdbp
,
false
)
;
return
rc
;
}
// end of CntReadNext
/***********************************************************************/
...
...
storage/connect/ha_connect.cc
View file @
56114a41
...
...
@@ -170,18 +170,18 @@
#define SZWMIN 4194304 // Minimum work area size 4M
extern
"C"
{
char
version
[]
=
"Version 1.03.0006 January 13, 2015"
;
char
compver
[]
=
"Version 1.03.0006 "
__DATE__
" "
__TIME__
;
char
version
[]
=
"Version 1.03.0006 February 06, 2015"
;
#if defined(WIN32)
char
compver
[]
=
"Version 1.03.0006 "
__DATE__
" "
__TIME__
;
char
slash
=
'\\'
;
#else // !WIN32
char
slash
=
'/'
;
#endif // !WIN32
// int trace= 0; // The general trace value
ulong
xconv
=
0
;
// The type conversion option
int
zconv
=
0
;
// The text conversion size
//
ulong xconv= 0; // The type conversion option
//
int zconv= 0; // The text conversion size
}
// extern "C"
#if defined(XMAP)
...
...
@@ -215,6 +215,8 @@ bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host,
const
char
*
db
,
char
*
tab
,
const
char
*
src
,
int
port
);
bool
ExactInfo
(
void
);
USETEMP
UseTemp
(
void
);
int
GetConvSize
(
void
);
TYPCONV
GetTypeConv
(
void
);
uint
GetWorkSize
(
void
);
void
SetWorkSize
(
uint
);
extern
"C"
const
char
*
msglang
(
void
);
...
...
@@ -289,6 +291,38 @@ static MYSQL_THDVAR_UINT(work_size,
"Size of the CONNECT work area."
,
NULL
,
NULL
,
SZWORK
,
SZWMIN
,
UINT_MAX
,
1
);
// Size used when converting TEXT columns to VARCHAR
static
MYSQL_THDVAR_INT
(
conv_size
,
PLUGIN_VAR_RQCMDARG
,
// opt
"Size used when converting TEXT columns."
,
NULL
,
NULL
,
SZCONV
,
0
,
65500
,
1
);
/**
Type conversion:
no: Unsupported types -> TYPE_ERROR
yes: TEXT -> VARCHAR
skip: skip unsupported type columns in Discovery
*/
const
char
*
xconv_names
[]
=
{
"NO"
,
"YES"
,
"SKIP"
,
NullS
};
TYPELIB
xconv_typelib
=
{
array_elements
(
xconv_names
)
-
1
,
"xconv_typelib"
,
xconv_names
,
NULL
};
static
MYSQL_THDVAR_ENUM
(
type_conv
,
// name
PLUGIN_VAR_RQCMDARG
,
// opt
"Unsupported types conversion."
,
// comment
NULL
,
// check
NULL
,
// update function
0
,
// def (no)
&
xconv_typelib
);
// typelib
#if defined(XMSG) || defined(NEWMSG)
const
char
*
language_names
[]
=
{
...
...
@@ -317,6 +351,8 @@ static MYSQL_THDVAR_ENUM(
extern
"C"
int
GetTraceValue
(
void
)
{
return
THDVAR
(
current_thd
,
xtrace
);}
bool
ExactInfo
(
void
)
{
return
THDVAR
(
current_thd
,
exact_info
);}
USETEMP
UseTemp
(
void
)
{
return
(
USETEMP
)
THDVAR
(
current_thd
,
use_tempfile
);}
int
GetConvSize
(
void
)
{
return
THDVAR
(
current_thd
,
conv_size
);}
TYPCONV
GetTypeConv
(
void
)
{
return
(
TYPCONV
)
THDVAR
(
current_thd
,
type_conv
);}
uint
GetWorkSize
(
void
)
{
return
THDVAR
(
current_thd
,
work_size
);}
void
SetWorkSize
(
uint
n
)
{
...
...
@@ -598,7 +634,11 @@ static int connect_init_func(void *p)
}
#endif // 0 (LINUX)
#if defined(WIN32)
sql_print_information
(
"CONNECT: %s"
,
compver
);
#else // !WIN32
sql_print_information
(
"CONNECT: %s"
,
version
);
#endif // !WIN32
#ifdef LIBXML2_SUPPORT
XmlInitParserLib
();
...
...
@@ -934,6 +974,9 @@ ulonglong ha_connect::table_flags() const
char
*
GetListOption
(
PGLOBAL
g
,
const
char
*
opname
,
const
char
*
oplist
,
const
char
*
def
)
{
if
(
!
oplist
)
return
(
char
*
)
def
;
char
key
[
16
],
val
[
256
];
char
*
pk
,
*
pv
,
*
pn
;
char
*
opval
=
(
char
*
)
def
;
...
...
@@ -997,8 +1040,12 @@ char *ha_connect::GetRealString(const char *s)
char
*
sv
;
if
(
IsPartitioned
()
&&
s
)
{
sv
=
(
char
*
)
PlugSubAlloc
(
xp
->
g
,
NULL
,
strlen
(
s
)
+
strlen
(
partname
));
// 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
);
sprintf
(
sv
,
s
,
partname
);
PlugSubAlloc
(
xp
->
g
,
NULL
,
strlen
(
sv
)
+
1
);
}
else
sv
=
(
char
*
)
s
;
...
...
@@ -1064,9 +1111,16 @@ char *ha_connect::GetStringOption(char *opname, char *sdef)
}
// endif Table_charset
if
(
!
opval
&&
options
&&
options
->
oplist
)
if
(
!
opval
&&
options
&&
options
->
oplist
)
{
opval
=
GetListOption
(
xp
->
g
,
opname
,
options
->
oplist
);
if
(
opval
&&
(
!
stricmp
(
opname
,
"connect"
)
||
!
stricmp
(
opname
,
"tabname"
)
||
!
stricmp
(
opname
,
"filename"
)))
opval
=
GetRealString
(
opval
);
}
// endif opval
if
(
!
opval
)
{
if
(
sdef
&&
!
strcmp
(
sdef
,
"*"
))
{
// Return the handler default value
...
...
@@ -2467,6 +2521,8 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
char
*
body
=
filp
->
Body
;
unsigned
int
i
;
bool
ismul
=
false
,
x
=
(
tty
==
TYPE_AM_MYX
||
tty
==
TYPE_AM_XDBC
);
bool
nonul
=
(
tty
==
TYPE_AM_ODBC
&&
(
tdbp
->
GetMode
()
==
MODE_INSERT
||
tdbp
->
GetMode
()
==
MODE_DELETE
));
OPVAL
vop
=
OP_XX
;
if
(
!
cond
)
...
...
@@ -2503,7 +2559,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
for
(
i
=
0
;
i
<
arglist
->
elements
;
i
++
)
if
((
subitem
=
li
++
))
{
if
(
!
CheckCond
(
g
,
filp
,
tty
,
subitem
))
{
if
(
vop
==
OP_OR
)
if
(
vop
==
OP_OR
||
nonul
)
return
NULL
;
else
*
p2
=
0
;
...
...
@@ -2599,6 +2655,8 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
if
(
trace
)
{
htrc
(
"Field index=%d
\n
"
,
pField
->
field
->
field_index
);
htrc
(
"Field name=%s
\n
"
,
pField
->
field
->
field_name
);
htrc
(
"Field type=%d
\n
"
,
pField
->
field
->
type
());
htrc
(
"Field_type=%d
\n
"
,
args
[
i
]
->
field_type
());
}
// endif trace
// IN and BETWEEN clauses should be col VOP list
...
...
@@ -2618,8 +2676,9 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
char
buff
[
256
];
String
*
res
,
tmp
(
buff
,
sizeof
(
buff
),
&
my_charset_bin
);
Item_basic_constant
*
pval
=
(
Item_basic_constant
*
)
args
[
i
];
Item
::
Type
type
=
args
[
i
]
->
real_type
();
switch
(
args
[
i
]
->
real_type
()
)
{
switch
(
type
)
{
case
COND
:
:
STRING_ITEM
:
case
COND
:
:
INT_ITEM
:
case
COND
:
:
REAL_ITEM
:
...
...
@@ -2644,10 +2703,64 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, AMT tty, Item *cond)
if
(
!
x
)
{
// Append the value to the filter
if
(
args
[
i
]
->
field_type
()
==
MYSQL_TYPE_VARCHAR
)
strcat
(
strncat
(
strcat
(
body
,
"'"
),
res
->
ptr
(),
res
->
length
()),
"'"
);
else
switch
(
args
[
i
]
->
field_type
())
{
case
MYSQL_TYPE_TIMESTAMP
:
case
MYSQL_TYPE_DATETIME
:
if
(
tty
==
TYPE_AM_ODBC
)
{
strcat
(
body
,
"{ts '"
);
strcat
(
strncat
(
body
,
res
->
ptr
(),
res
->
length
()),
"'}"
);
break
;
}
// endif ODBC
case
MYSQL_TYPE_DATE
:
if
(
tty
==
TYPE_AM_ODBC
)
{
strcat
(
body
,
"{d '"
);
strcat
(
strncat
(
body
,
res
->
ptr
(),
res
->
length
()),
"'}"
);
break
;
}
// endif ODBC
case
MYSQL_TYPE_TIME
:
if
(
tty
==
TYPE_AM_ODBC
)
{
strcat
(
body
,
"{t '"
);
strcat
(
strncat
(
body
,
res
->
ptr
(),
res
->
length
()),
"'}"
);
break
;
}
// endif ODBC
case
MYSQL_TYPE_VARCHAR
:
if
(
tty
==
TYPE_AM_ODBC
&&
i
)
{
switch
(
args
[
0
]
->
field_type
())
{
case
MYSQL_TYPE_TIMESTAMP
:
case
MYSQL_TYPE_DATETIME
:
strcat
(
body
,
"{ts '"
);
strncat
(
body
,
res
->
ptr
(),
res
->
length
());
strcat
(
body
,
"'}"
);
break
;
case
MYSQL_TYPE_DATE
:
strcat
(
body
,
"{d '"
);
strncat
(
body
,
res
->
ptr
(),
res
->
length
());
strcat
(
body
,
"'}"
);
break
;
case
MYSQL_TYPE_TIME
:
strcat
(
body
,
"{t '"
);
strncat
(
body
,
res
->
ptr
(),
res
->
length
());
strcat
(
body
,
"'}"
);
break
;
default:
strcat
(
body
,
"'"
);
strncat
(
body
,
res
->
ptr
(),
res
->
length
());
strcat
(
body
,
"'"
);
}
// endswitch field type
}
else
{
strcat
(
body
,
"'"
);
strncat
(
body
,
res
->
ptr
(),
res
->
length
());
strcat
(
body
,
"'"
);
}
// endif tty
break
;
default:
strncat
(
body
,
res
->
ptr
(),
res
->
length
());
}
// endswitch field type
}
else
{
if
(
args
[
i
]
->
field_type
()
==
MYSQL_TYPE_VARCHAR
)
{
...
...
@@ -2753,7 +2866,7 @@ const COND *ha_connect::cond_push(const COND *cond)
}
else
if
(
x
&&
cond
)
tdbp
->
SetCondFil
(
filp
);
// Wrong filter
}
else
}
else
if
(
tty
!=
TYPE_AM_JSN
&&
tty
!=
TYPE_AM_JSON
)
tdbp
->
SetFilter
(
CondFilter
(
g
,
(
Item
*
)
cond
));
fin:
...
...
@@ -4620,7 +4733,7 @@ static bool add_field(String *sql, const char *field_name, int typ,
char
*
dft
,
char
*
xtra
,
int
flag
,
bool
dbf
,
char
v
)
{
char
var
=
(
len
>
255
)
?
'V'
:
v
;
bool
error
=
false
;
bool
q
,
error
=
false
;
const
char
*
type
=
PLGtoMYSQLtype
(
typ
,
dbf
,
var
);
error
|=
sql
->
append
(
'`'
);
...
...
@@ -4661,7 +4774,12 @@ static bool add_field(String *sql, const char *field_name, int typ,
if
(
dft
&&
*
dft
)
{
error
|=
sql
->
append
(
" DEFAULT "
);
if
(
!
IsTypeNum
(
typ
))
{
if
(
typ
==
TYPE_DATE
)
q
=
(
strspn
(
dft
,
"0123456789 -:/"
)
==
strlen
(
dft
));
else
q
=
!
IsTypeNum
(
typ
);
if
(
q
)
{
error
|=
sql
->
append
(
"'"
);
error
|=
sql
->
append_for_single_quote
(
dft
,
strlen
(
dft
));
error
|=
sql
->
append
(
"'"
);
...
...
@@ -4831,6 +4949,9 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
int
port
=
0
,
hdr
=
0
,
mxr
__attribute__
((
unused
))
=
0
,
mxe
=
0
,
rc
=
0
;
int
cop
__attribute__
((
unused
))
=
0
;
#if defined(ODBC_SUPPORT)
POPARM
sop
=
NULL
;
char
*
ucnc
=
NULL
;
bool
cnc
=
false
;
int
cto
=
-
1
,
qto
=
-
1
;
#endif // ODBC_SUPPORT
uint
tm
,
fnc
=
FNC_NO
,
supfnc
=
(
FNC_NO
|
FNC_COL
);
...
...
@@ -4875,7 +4996,8 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
if
(
topt
->
oplist
)
{
host
=
GetListOption
(
g
,
"host"
,
topt
->
oplist
,
"localhost"
);
user
=
GetListOption
(
g
,
"user"
,
topt
->
oplist
,
"root"
);
user
=
GetListOption
(
g
,
"user"
,
topt
->
oplist
,
(
ttp
==
TAB_ODBC
?
NULL
:
"root"
));
// Default value db can come from the DBNAME=xxx option.
db
=
GetListOption
(
g
,
"database"
,
topt
->
oplist
,
db
);
col
=
GetListOption
(
g
,
"colist"
,
topt
->
oplist
,
col
);
...
...
@@ -4894,6 +5016,9 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
mxr
=
atoi
(
GetListOption
(
g
,
"maxres"
,
topt
->
oplist
,
"0"
));
cto
=
atoi
(
GetListOption
(
g
,
"ConnectTimeout"
,
topt
->
oplist
,
"-1"
));
qto
=
atoi
(
GetListOption
(
g
,
"QueryTimeout"
,
topt
->
oplist
,
"-1"
));
if
((
ucnc
=
GetListOption
(
g
,
"UseDSN"
,
topt
->
oplist
)))
cnc
=
(
!*
ucnc
||
*
ucnc
==
'y'
||
*
ucnc
==
'Y'
||
atoi
(
ucnc
)
!=
0
);
#endif
mxe
=
atoi
(
GetListOption
(
g
,
"maxerr"
,
topt
->
oplist
,
"0"
));
#if defined(PROMPT_OK)
...
...
@@ -4901,7 +5026,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
#endif // PROMPT_OK
}
else
{
host
=
"localhost"
;
user
=
"root"
;
user
=
(
ttp
==
TAB_ODBC
?
NULL
:
"root"
)
;
}
// endif option_list
if
(
!
(
shm
=
(
char
*
)
db
))
...
...
@@ -4978,10 +5103,18 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
}
// endif dsn
#endif // PROMPT_OK
}
else
if
(
!
dsn
)
}
else
if
(
!
dsn
)
{
sprintf
(
g
->
Message
,
"Missing %s connection string"
,
topt
->
type
);
else
}
else
{
// Store ODBC additional parameters
sop
=
(
POPARM
)
PlugSubAlloc
(
g
,
NULL
,
sizeof
(
ODBCPARM
));
sop
->
User
=
(
char
*
)
user
;
sop
->
Pwd
=
(
char
*
)
pwd
;
sop
->
Cto
=
cto
;
sop
->
Qto
=
qto
;
sop
->
UseCnc
=
cnc
;
ok
=
true
;
}
// endif's
supfnc
|=
(
FNC_TABLE
|
FNC_DSN
|
FNC_DRIVER
);
break
;
...
...
@@ -5112,15 +5245,15 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
case
FNC_NO
:
case
FNC_COL
:
if
(
src
)
{
qrp
=
ODBCSrcCols
(
g
,
dsn
,
(
char
*
)
src
,
cto
,
qto
);
qrp
=
ODBCSrcCols
(
g
,
dsn
,
(
char
*
)
src
,
sop
);
src
=
NULL
;
// for next tests
}
else
qrp
=
ODBCColumns
(
g
,
dsn
,
shm
,
tab
,
NULL
,
mxr
,
cto
,
qto
,
fnc
==
FNC_COL
);
mxr
,
fnc
==
FNC_COL
,
sop
);
break
;
case
FNC_TABLE
:
qrp
=
ODBCTables
(
g
,
dsn
,
shm
,
tab
,
mxr
,
cto
,
qto
,
true
);
qrp
=
ODBCTables
(
g
,
dsn
,
shm
,
tab
,
mxr
,
true
,
sop
);
break
;
case
FNC_DSN
:
qrp
=
ODBCDataSources
(
g
,
mxr
,
true
);
...
...
@@ -5237,9 +5370,10 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
for
(
crp
=
qrp
->
Colresp
;
crp
;
crp
=
crp
->
Next
)
switch
(
crp
->
Fld
)
{
case
FLD_NAME
:
if
(
ttp
==
TAB_CSV
&&
topt
->
data_charset
&&
if
(
ttp
==
TAB_PRX
||
(
ttp
==
TAB_CSV
&&
topt
->
data_charset
&&
(
!
stricmp
(
topt
->
data_charset
,
"UTF8"
)
||
!
stricmp
(
topt
->
data_charset
,
"UTF-8"
)))
!
stricmp
(
topt
->
data_charset
,
"UTF-8"
)))
)
cnm
=
crp
->
Kdata
->
GetCharValue
(
i
);
else
cnm
=
encode
(
g
,
crp
->
Kdata
->
GetCharValue
(
i
));
...
...
@@ -5299,9 +5433,18 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
// typ must be PLG type, not SQL type
if
(
!
(
plgtyp
=
TranslateSQLType
(
typ
,
dec
,
prec
,
v
)))
{
if
(
GetTypeConv
()
==
TPC_SKIP
)
{
// Skip this column
sprintf
(
g
->
Message
,
"Column %s skipped (unsupported type %d)"
,
cnm
,
typ
);
push_warning
(
thd
,
Sql_condition
::
WARN_LEVEL_WARN
,
0
,
g
->
Message
);
continue
;
}
else
{
sprintf
(
g
->
Message
,
"Unsupported SQL type %d"
,
typ
);
my_message
(
ER_UNKNOWN_ERROR
,
g
->
Message
,
MYF
(
0
));
goto
err
;
}
// endif type_conv
}
else
typ
=
plgtyp
;
...
...
@@ -6341,58 +6484,6 @@ struct st_mysql_storage_engine connect_storage_engine=
/***********************************************************************/
/* CONNECT global variables definitions. */
/***********************************************************************/
// Size used when converting TEXT columns to VARCHAR
#if defined(_DEBUG)
static
MYSQL_SYSVAR_INT
(
conv_size
,
zconv
,
PLUGIN_VAR_RQCMDARG
,
// opt
"Size used when converting TEXT columns."
,
NULL
,
NULL
,
SZCONV
,
0
,
65500
,
1
);
#else
static
MYSQL_SYSVAR_INT
(
conv_size
,
zconv
,
PLUGIN_VAR_RQCMDARG
|
PLUGIN_VAR_READONLY
,
// opt
"Size used when converting TEXT columns."
,
NULL
,
NULL
,
SZCONV
,
0
,
65500
,
1
);
#endif
/**
Type conversion:
no: Unsupported types -> TYPE_ERROR
yes: TEXT -> VARCHAR
skip: skip unsupported type columns in Discovery
*/
const
char
*
xconv_names
[]
=
{
"NO"
,
"YES"
,
"SKIP"
,
NullS
};
TYPELIB
xconv_typelib
=
{
array_elements
(
xconv_names
)
-
1
,
"xconv_typelib"
,
xconv_names
,
NULL
};
#if defined(_DEBUG)
static
MYSQL_SYSVAR_ENUM
(
type_conv
,
// name
xconv
,
// varname
PLUGIN_VAR_RQCMDARG
,
// opt
"Unsupported types conversion."
,
// comment
NULL
,
// check
NULL
,
// update function
0
,
// def (no)
&
xconv_typelib
);
// typelib
#else
static
MYSQL_SYSVAR_ENUM
(
type_conv
,
// name
xconv
,
// varname
PLUGIN_VAR_RQCMDARG
|
PLUGIN_VAR_READONLY
,
"Unsupported types conversion."
,
// comment
NULL
,
// check
NULL
,
// update function
0
,
// def (no)
&
xconv_typelib
);
// typelib
#endif
#if defined(XMAP)
// Using file mapping for indexes if true
static
MYSQL_SYSVAR_BOOL
(
indx_map
,
xmap
,
PLUGIN_VAR_RQCMDARG
,
...
...
storage/connect/json.cpp
View file @
56114a41
...
...
@@ -34,7 +34,7 @@
/***********************************************************************/
PJSON
ParseJson
(
PGLOBAL
g
,
char
*
s
,
int
len
,
int
pretty
,
bool
*
comma
)
{
int
i
;
int
i
,
rc
;
bool
b
=
false
;
PJSON
jsp
=
NULL
;
STRG
src
;
...
...
@@ -48,22 +48,32 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma)
src
.
str
=
s
;
src
.
len
=
len
;
// Save stack and allocation environment and prepare error return
if
(
g
->
jump_level
==
MAX_JUMP
)
{
strcpy
(
g
->
Message
,
MSG
(
TOO_MANY_JUMPS
));
return
NULL
;
}
// endif jump_level
if
((
rc
=
setjmp
(
g
->
jumper
[
++
g
->
jump_level
]))
!=
0
)
{
goto
err
;
}
// endif rc
for
(
i
=
0
;
i
<
len
;
i
++
)
switch
(
s
[
i
])
{
case
'['
:
if
(
jsp
)
{
strcpy
(
g
->
Message
,
"More than one item in file"
);
return
NULL
;
goto
err
;
}
else
if
(
!
(
jsp
=
ParseArray
(
g
,
++
i
,
src
)))
return
NULL
;
goto
err
;
break
;
case
'{'
:
if
(
jsp
)
{
strcpy
(
g
->
Message
,
"More than one item in file"
);
return
NULL
;
goto
err
;
}
else
if
(
!
(
jsp
=
ParseObject
(
g
,
++
i
,
src
)))
return
NULL
;
goto
err
;
break
;
case
' '
:
case
'\t'
:
...
...
@@ -79,7 +89,7 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma)
}
// endif pretty
sprintf
(
g
->
Message
,
"Unexpected ',' (pretty=%d)"
,
pretty
);
return
NULL
;
goto
err
;
case
'('
:
b
=
true
;
break
;
...
...
@@ -92,13 +102,18 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int pretty, bool *comma)
default:
sprintf
(
g
->
Message
,
"Bad '%c' character near %.*s"
,
s
[
i
],
ARGS
);
return
NULL
;
goto
err
;
};
// endswitch s[i]
if
(
!
jsp
)
sprintf
(
g
->
Message
,
"Invalid Json string '%.*s'"
,
50
,
s
);
g
->
jump_level
--
;
return
jsp
;
err:
g
->
jump_level
--
;
return
NULL
;
}
// end of ParseJson
/***********************************************************************/
...
...
@@ -312,18 +327,25 @@ PJVAL ParseValue(PGLOBAL g, int& i, STRG& src)
/***********************************************************************/
char
*
ParseString
(
PGLOBAL
g
,
int
&
i
,
STRG
&
src
)
{
char
*
p
,
*
s
=
src
.
str
;
char
*
s
=
src
.
str
;
uchar
*
p
;
int
n
=
0
,
len
=
src
.
len
;
// Be sure of memory availability
if
(
len
+
1
-
i
>
(
signed
)((
PPOOLHEADER
)
g
->
Sarea
)
->
FreeBlk
)
{
strcpy
(
g
->
Message
,
"ParseString: Out of memory"
);
return
NULL
;
}
// endif len
// The size to allocate is not known yet
p
=
(
char
*
)
PlugSubAlloc
(
g
,
NULL
,
0
);
p
=
(
uchar
*
)
PlugSubAlloc
(
g
,
NULL
,
0
);
for
(;
i
<
len
;
i
++
)
switch
(
s
[
i
])
{
case
'"'
:
p
[
n
++
]
=
0
;
PlugSubAlloc
(
g
,
NULL
,
n
);
return
p
;
return
(
char
*
)
p
;
case
'\\'
:
if
(
++
i
<
len
)
{
if
(
s
[
i
]
==
'u'
)
{
...
...
@@ -504,8 +526,11 @@ PSZ Serialize(PGLOBAL g, PJSON jsp, FILE *fs, int pretty)
err
=
(
b
&&
jp
->
WriteChr
(
'\t'
));
err
|=
SerializeObject
(
jp
,
(
PJOB
)
jsp
);
break
;
case
TYPE_JVAL
:
err
=
SerializeValue
(
jp
,
(
PJVAL
)
jsp
);
break
;
default:
strcpy
(
g
->
Message
,
"
json tree is not an Array or an Object"
);
strcpy
(
g
->
Message
,
"
Invalid json tree"
);
}
// endswitch Type
if
(
fs
)
{
...
...
@@ -575,9 +600,9 @@ bool SerializeObject(JOUT *js, PJOB jobp)
else
if
(
js
->
WriteChr
(
','
))
return
true
;
if
(
js
->
WriteChr
(
'
\"'
)
||
if
(
js
->
WriteChr
(
'
"'
)
||
js
->
WriteStr
(
pair
->
Key
)
||
js
->
WriteChr
(
'
\"'
)
||
js
->
WriteChr
(
'
"'
)
||
js
->
WriteChr
(
':'
)
||
SerializeValue
(
js
,
pair
->
Val
))
return
true
;
...
...
@@ -675,12 +700,13 @@ bool JOUTSTR::Escape(const char *s)
for
(
unsigned
int
i
=
0
;
i
<
strlen
(
s
);
i
++
)
switch
(
s
[
i
])
{
case
'"'
:
case
'\\'
:
case
'\t'
:
case
'\n'
:
case
'\r'
:
case
'\b'
:
case
'\f'
:
case
'"'
:
WriteChr
(
'\\'
);
case
'\f'
:
WriteChr
(
'\\'
);
// passthru
default:
WriteChr
(
s
[
i
]);
...
...
@@ -723,12 +749,13 @@ bool JOUTFILE::Escape(const char *s)
for
(
unsigned
int
i
=
0
;
i
<
strlen
(
s
);
i
++
)
switch
(
s
[
i
])
{
case
'"'
:
fputs
(
"
\\\"
"
,
Stream
);
break
;
case
'\\'
:
fputs
(
"
\\\\
"
,
Stream
);
break
;
case
'\t'
:
fputs
(
"
\\
t"
,
Stream
);
break
;
case
'\n'
:
fputs
(
"
\\
n"
,
Stream
);
break
;
case
'\r'
:
fputs
(
"
\\
r"
,
Stream
);
break
;
case
'\b'
:
fputs
(
"
\\
b"
,
Stream
);
break
;
case
'\f'
:
fputs
(
"
\\
f"
,
Stream
);
break
;
case
'"'
:
fputs
(
"
\\\"
"
,
Stream
);
break
;
default:
fputc
(
s
[
i
],
Stream
);
break
;
...
...
@@ -1053,3 +1080,27 @@ PSZ JVALUE::GetString(void)
return
(
Value
)
?
Value
->
GetCharString
(
buf
)
:
NULL
;
}
// end of GetString
/***********************************************************************/
/* Set the Value's value as the given integer. */
/***********************************************************************/
void
JVALUE
::
SetInteger
(
PGLOBAL
g
,
int
n
)
{
Value
=
AllocateValue
(
g
,
&
n
,
TYPE_INT
);
}
// end of AddInteger
/***********************************************************************/
/* Set the Value's value as the given DOUBLE. */
/***********************************************************************/
void
JVALUE
::
SetFloat
(
PGLOBAL
g
,
double
f
)
{
Value
=
AllocateValue
(
g
,
&
f
,
TYPE_DOUBLE
,
6
);
}
// end of AddFloat
/***********************************************************************/
/* Set the Value's value as the given string. */
/***********************************************************************/
void
JVALUE
::
SetString
(
PGLOBAL
g
,
PSZ
s
)
{
Value
=
AllocateValue
(
g
,
s
,
TYPE_STRING
);
}
// end of AddFloat
storage/connect/json.h
View file @
56114a41
...
...
@@ -18,7 +18,8 @@ enum JTYP {TYPE_STRG = 1,
TYPE_BOOL
=
4
,
TYPE_INTG
=
7
,
TYPE_JSON
=
12
,
TYPE_JAR
,
TYPE_JOB
,
TYPE_JAR
,
TYPE_JOB
,
TYPE_JVAL
};
class
JOUT
;
...
...
@@ -156,6 +157,9 @@ class JSON : public BLOCK {
virtual
void
SetValue
(
PGLOBAL
g
,
PJVAL
jvp
,
PSZ
key
)
{
X
}
virtual
void
SetValue
(
PVAL
valp
)
{
X
}
virtual
void
SetValue
(
PJSON
jsp
)
{
X
}
virtual
void
SetString
(
PGLOBAL
g
,
PSZ
s
)
{
X
}
virtual
void
SetInteger
(
PGLOBAL
g
,
int
n
)
{
X
}
virtual
void
SetFloat
(
PGLOBAL
g
,
double
f
)
{
X
}
virtual
bool
DeleteValue
(
int
i
)
{
X
return
true
;}
protected:
...
...
@@ -171,6 +175,8 @@ class JOBJECT : public JSON {
public:
JOBJECT
(
void
)
:
JSON
()
{
First
=
Last
=
NULL
;}
using
JSON
::
GetValue
;
using
JSON
::
SetValue
;
virtual
void
Clear
(
void
)
{
First
=
Last
=
NULL
;
Size
=
0
;}
virtual
JTYP
GetType
(
void
)
{
return
TYPE_JOB
;}
virtual
PJPR
AddPair
(
PGLOBAL
g
,
PSZ
key
);
...
...
@@ -192,6 +198,8 @@ class JARRAY : public JSON {
public:
JARRAY
(
void
)
:
JSON
()
{
Alloc
=
0
;
First
=
Last
=
NULL
;
Mvals
=
NULL
;}
using
JSON
::
GetValue
;
using
JSON
::
SetValue
;
virtual
void
Clear
(
void
)
{
First
=
Last
=
NULL
;
Size
=
0
;}
virtual
JTYP
GetType
(
void
)
{
return
TYPE_JAR
;}
virtual
PJAR
GetArray
(
void
)
{
return
this
;}
...
...
@@ -223,6 +231,8 @@ class JVALUE : public JSON {
{
Jsp
=
jsp
;
Value
=
NULL
;
Next
=
NULL
;
Del
=
false
;}
JVALUE
(
PGLOBAL
g
,
PVAL
valp
);
using
JSON
::
GetValue
;
using
JSON
::
SetValue
;
virtual
void
Clear
(
void
)
{
Jsp
=
NULL
;
Value
=
NULL
;
Next
=
NULL
;
Del
=
false
;
Size
=
0
;}
virtual
JTYP
GetType
(
void
)
{
return
TYPE_JVAL
;}
...
...
@@ -236,6 +246,9 @@ class JVALUE : public JSON {
virtual
PSZ
GetString
(
void
);
virtual
void
SetValue
(
PVAL
valp
)
{
Value
=
valp
;}
virtual
void
SetValue
(
PJSON
jsp
)
{
Jsp
=
jsp
;}
virtual
void
SetString
(
PGLOBAL
g
,
PSZ
s
);
virtual
void
SetInteger
(
PGLOBAL
g
,
int
n
);
virtual
void
SetFloat
(
PGLOBAL
g
,
double
f
);
protected:
PJSON
Jsp
;
// To the json value
...
...
storage/connect/jsonudf.cpp
0 → 100644
View file @
56114a41
/************* jsonudf C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: jsonudf Version 1.0 */
/* (C) Copyright to the author Olivier BERTRAND 2015 */
/* This program are the JSON User Defined Functions . */
/***********************************************************************/
/***********************************************************************/
/* Include relevant sections of the MariaDB header file. */
/***********************************************************************/
#include <my_global.h>
#include <mysql.h>
#include "global.h"
#include "plgdbsem.h"
#include "json.h"
extern
"C"
{
DllExport
my_bool
Json_Value_init
(
UDF_INIT
*
,
UDF_ARGS
*
,
char
*
);
DllExport
char
*
Json_Value
(
UDF_INIT
*
,
UDF_ARGS
*
,
char
*
,
unsigned
long
*
,
char
*
,
char
*
);
DllExport
void
Json_Value_deinit
(
UDF_INIT
*
);
DllExport
my_bool
Json_Array_init
(
UDF_INIT
*
,
UDF_ARGS
*
,
char
*
);
DllExport
char
*
Json_Array
(
UDF_INIT
*
,
UDF_ARGS
*
,
char
*
,
unsigned
long
*
,
char
*
,
char
*
);
DllExport
void
Json_Array_deinit
(
UDF_INIT
*
);
DllExport
my_bool
Json_Object_init
(
UDF_INIT
*
,
UDF_ARGS
*
,
char
*
);
DllExport
char
*
Json_Object
(
UDF_INIT
*
,
UDF_ARGS
*
,
char
*
,
unsigned
long
*
,
char
*
,
char
*
);
DllExport
void
Json_Object_deinit
(
UDF_INIT
*
);
DllExport
my_bool
Json_Array_Grp_init
(
UDF_INIT
*
,
UDF_ARGS
*
,
char
*
);
DllExport
void
Json_Array_Grp_add
(
UDF_INIT
*
,
UDF_ARGS
*
,
char
*
,
char
*
);
DllExport
char
*
Json_Array_Grp
(
UDF_INIT
*
,
UDF_ARGS
*
,
char
*
,
unsigned
long
*
,
char
*
,
char
*
);
DllExport
void
Json_Array_Grp_clear
(
UDF_INIT
*
,
char
*
,
char
*
);
DllExport
void
Json_Array_Grp_deinit
(
UDF_INIT
*
);
DllExport
my_bool
Json_Object_Grp_init
(
UDF_INIT
*
,
UDF_ARGS
*
,
char
*
);
DllExport
void
Json_Object_Grp_add
(
UDF_INIT
*
,
UDF_ARGS
*
,
char
*
,
char
*
);
DllExport
char
*
Json_Object_Grp
(
UDF_INIT
*
,
UDF_ARGS
*
,
char
*
,
unsigned
long
*
,
char
*
,
char
*
);
DllExport
void
Json_Object_Grp_clear
(
UDF_INIT
*
,
char
*
,
char
*
);
DllExport
void
Json_Object_Grp_deinit
(
UDF_INIT
*
);
}
// extern "C"
/***********************************************************************/
/* Allocate and initialise the memory area. */
/***********************************************************************/
static
my_bool
JsonInit
(
UDF_INIT
*
initid
,
char
*
message
,
unsigned
long
reslen
,
unsigned
long
memlen
)
{
PGLOBAL
g
=
PlugInit
(
NULL
,
memlen
);
if
(
!
g
)
{
strcpy
(
message
,
"Allocation error"
);
return
true
;
}
else
if
(
g
->
Sarea_Size
==
0
)
{
strcpy
(
message
,
g
->
Message
);
PlugExit
(
g
);
return
true
;
}
else
initid
->
ptr
=
(
char
*
)
g
;
initid
->
maybe_null
=
false
;
initid
->
max_length
=
reslen
;
return
false
;
}
// end of Json_Object_init
/***********************************************************************/
/* Returns true if the argument is a JSON string. */
/***********************************************************************/
static
my_bool
IsJson
(
UDF_ARGS
*
args
,
int
i
)
{
return
(
args
->
arg_type
[
i
]
==
STRING_RESULT
&&
!
strnicmp
(
args
->
attributes
[
i
],
"Json_"
,
5
));
}
// end of IsJson
/***********************************************************************/
/* Calculate the reslen and memlen needed by a function. */
/***********************************************************************/
static
my_bool
CalcLen
(
UDF_ARGS
*
args
,
my_bool
obj
,
unsigned
long
&
reslen
,
unsigned
long
&
memlen
)
{
unsigned
long
i
,
k
;
reslen
=
args
->
arg_count
+
2
;
// Calculate the result max length
for
(
i
=
0
;
i
<
args
->
arg_count
;
i
++
)
{
if
(
obj
)
{
if
(
!
(
k
=
args
->
attribute_lengths
[
i
]))
k
=
strlen
(
args
->
attributes
[
i
]);
reslen
+=
(
k
+
3
);
// For quotes and :
}
// endif obj
switch
(
args
->
arg_type
[
i
])
{
case
STRING_RESULT
:
if
(
IsJson
(
args
,
i
))
reslen
+=
args
->
lengths
[
i
];
else
reslen
+=
(
args
->
lengths
[
i
]
+
1
)
*
2
;
// Pessimistic !
break
;
case
INT_RESULT
:
reslen
+=
20
;
break
;
case
REAL_RESULT
:
reslen
+=
31
;
break
;
case
DECIMAL_RESULT
:
reslen
+=
(
args
->
lengths
[
i
]
+
7
);
// 6 decimals
break
;
case
TIME_RESULT
:
case
ROW_RESULT
:
case
IMPOSSIBLE_RESULT
:
default:
// What should we do here ?
break
;
}
// endswitch arg_type
}
// endfor i
// Calculate the amount of memory needed
memlen
=
1024
+
sizeof
(
JOUTSTR
)
+
reslen
;
for
(
i
=
0
;
i
<
args
->
arg_count
;
i
++
)
{
memlen
+=
(
args
->
lengths
[
i
]
+
sizeof
(
JVALUE
));
if
(
obj
)
{
if
(
!
(
k
=
args
->
attribute_lengths
[
i
]))
k
=
strlen
(
args
->
attributes
[
i
]);
memlen
+=
(
k
+
sizeof
(
JOBJECT
)
+
sizeof
(
JPAIR
));
}
else
memlen
+=
sizeof
(
JARRAY
);
switch
(
args
->
arg_type
[
i
])
{
case
STRING_RESULT
:
if
(
IsJson
(
args
,
i
))
memlen
+=
args
->
lengths
[
i
]
*
5
;
// Estimate parse memory
memlen
+=
sizeof
(
TYPVAL
<
PSZ
>
);
break
;
case
INT_RESULT
:
memlen
+=
sizeof
(
TYPVAL
<
int
>
);
break
;
case
REAL_RESULT
:
case
DECIMAL_RESULT
:
memlen
+=
sizeof
(
TYPVAL
<
double
>
);
break
;
case
TIME_RESULT
:
case
ROW_RESULT
:
case
IMPOSSIBLE_RESULT
:
default:
// What should we do here ?
break
;
}
// endswitch arg_type
}
// endfor i
return
false
;
}
// end of CalcLen
/***********************************************************************/
/* Make a zero terminated string from the passed argument. */
/***********************************************************************/
static
PSZ
MakePSZ
(
PGLOBAL
g
,
UDF_ARGS
*
args
,
int
i
)
{
if
(
args
->
args
[
i
])
{
int
n
=
args
->
lengths
[
i
];
PSZ
s
=
(
PSZ
)
PlugSubAlloc
(
g
,
NULL
,
n
+
1
);
memcpy
(
s
,
args
->
args
[
i
],
n
);
s
[
n
]
=
0
;
return
s
;
}
else
return
NULL
;
}
// end of MakePSZ
/***********************************************************************/
/* Make a valid key from the passed argument. */
/***********************************************************************/
static
PSZ
MakeKey
(
PGLOBAL
g
,
UDF_ARGS
*
args
,
int
i
)
{
int
n
=
args
->
attribute_lengths
[
i
];
bool
b
;
// true if attribute is zero terminated
PSZ
p
,
s
=
args
->
attributes
[
i
];
if
(
s
&&
*
s
&&
(
n
||
*
s
==
'\''
))
{
if
((
b
=
(
!
n
||
!
s
[
n
])))
n
=
strlen
(
s
);
if
(
n
>
5
&&
IsJson
(
args
,
i
))
{
s
+=
5
;
n
-=
5
;
}
else
if
(
*
s
==
'\''
&&
s
[
n
-
1
]
==
'\''
)
{
s
++
;
n
-=
2
;
b
=
false
;
}
// endif *s
if
(
n
<
1
)
return
"Key"
;
if
(
!
b
)
{
p
=
(
PSZ
)
PlugSubAlloc
(
g
,
NULL
,
n
+
1
);
memcpy
(
p
,
s
,
n
);
p
[
n
]
=
0
;
s
=
p
;
}
// endif b
}
// endif s
return
s
;
}
// end of MakeKey
/***********************************************************************/
/* Make a JSON value from the passed argument. */
/***********************************************************************/
static
PJVAL
MakeValue
(
PGLOBAL
g
,
UDF_ARGS
*
args
,
int
i
)
{
char
*
sap
=
args
->
args
[
i
];
PJVAL
jvp
=
new
(
g
)
JVALUE
;
if
(
sap
)
switch
(
args
->
arg_type
[
i
])
{
case
STRING_RESULT
:
if
(
args
->
lengths
[
i
])
{
if
(
IsJson
(
args
,
i
))
jvp
->
SetValue
(
ParseJson
(
g
,
sap
,
args
->
lengths
[
i
],
0
));
else
jvp
->
SetString
(
g
,
MakePSZ
(
g
,
args
,
i
));
}
// endif str
break
;
case
INT_RESULT
:
jvp
->
SetInteger
(
g
,
*
(
int
*
)
sap
);
break
;
case
REAL_RESULT
:
jvp
->
SetFloat
(
g
,
*
(
double
*
)
sap
);
break
;
case
DECIMAL_RESULT
:
jvp
->
SetFloat
(
g
,
atof
(
MakePSZ
(
g
,
args
,
i
)));
break
;
case
TIME_RESULT
:
case
ROW_RESULT
:
case
IMPOSSIBLE_RESULT
:
default:
break
;
}
// endswitch arg_type
return
jvp
;
}
// end of MakeValue
/***********************************************************************/
/* Make a Json value containing the parameter. */
/***********************************************************************/
my_bool
Json_Value_init
(
UDF_INIT
*
initid
,
UDF_ARGS
*
args
,
char
*
message
)
{
unsigned
long
reslen
,
memlen
;
if
(
args
->
arg_count
>
1
)
{
strcpy
(
message
,
"Json_Value cannot accept more than 1 argument"
);
return
true
;
}
else
CalcLen
(
args
,
false
,
reslen
,
memlen
);
return
JsonInit
(
initid
,
message
,
reslen
,
memlen
);
}
// end of Json_Value_init
char
*
Json_Value
(
UDF_INIT
*
initid
,
UDF_ARGS
*
args
,
char
*
result
,
unsigned
long
*
res_length
,
char
*
is_null
,
char
*
error
)
{
char
*
str
;
PJVAL
jvp
;
PGLOBAL
g
=
(
PGLOBAL
)
initid
->
ptr
;
PlugSubSet
(
g
,
g
->
Sarea
,
g
->
Sarea_Size
);
jvp
=
MakeValue
(
g
,
args
,
0
);
if
(
!
(
str
=
Serialize
(
g
,
jvp
,
NULL
,
0
)))
str
=
strcpy
(
result
,
g
->
Message
);
*
res_length
=
strlen
(
str
);
return
str
;
}
// end of Json_Value
void
Json_Value_deinit
(
UDF_INIT
*
initid
)
{
PlugExit
((
PGLOBAL
)
initid
->
ptr
);
}
// end of Json_Value_deinit
/***********************************************************************/
/* Make a Json array containing all the parameters. */
/***********************************************************************/
my_bool
Json_Array_init
(
UDF_INIT
*
initid
,
UDF_ARGS
*
args
,
char
*
message
)
{
unsigned
long
reslen
,
memlen
;
CalcLen
(
args
,
false
,
reslen
,
memlen
);
return
JsonInit
(
initid
,
message
,
reslen
,
memlen
);
}
// end of Json_Array_init
char
*
Json_Array
(
UDF_INIT
*
initid
,
UDF_ARGS
*
args
,
char
*
result
,
unsigned
long
*
res_length
,
char
*
is_null
,
char
*
error
)
{
char
*
str
;
uint
i
;
PJAR
arp
;
PGLOBAL
g
=
(
PGLOBAL
)
initid
->
ptr
;
PlugSubSet
(
g
,
g
->
Sarea
,
g
->
Sarea_Size
);
arp
=
new
(
g
)
JARRAY
;
for
(
i
=
0
;
i
<
args
->
arg_count
;
i
++
)
arp
->
AddValue
(
g
,
MakeValue
(
g
,
args
,
i
));
arp
->
InitArray
(
g
);
if
(
!
(
str
=
Serialize
(
g
,
arp
,
NULL
,
0
)))
str
=
strcpy
(
result
,
g
->
Message
);
*
res_length
=
strlen
(
str
);
return
str
;
}
// end of Json_Array
void
Json_Array_deinit
(
UDF_INIT
*
initid
)
{
PlugExit
((
PGLOBAL
)
initid
->
ptr
);
}
// end of Json_Array_deinit
/***********************************************************************/
/* Make a Json Oject containing all the parameters. */
/***********************************************************************/
my_bool
Json_Object_init
(
UDF_INIT
*
initid
,
UDF_ARGS
*
args
,
char
*
message
)
{
unsigned
long
reslen
,
memlen
;
CalcLen
(
args
,
true
,
reslen
,
memlen
);
return
JsonInit
(
initid
,
message
,
reslen
,
memlen
);
}
// end of Json_Object_init
char
*
Json_Object
(
UDF_INIT
*
initid
,
UDF_ARGS
*
args
,
char
*
result
,
unsigned
long
*
res_length
,
char
*
is_null
,
char
*
error
)
{
char
*
str
;
uint
i
;
PJOB
objp
;
PGLOBAL
g
=
(
PGLOBAL
)
initid
->
ptr
;
PlugSubSet
(
g
,
g
->
Sarea
,
g
->
Sarea_Size
);
objp
=
new
(
g
)
JOBJECT
;
for
(
i
=
0
;
i
<
args
->
arg_count
;
i
++
)
objp
->
SetValue
(
g
,
MakeValue
(
g
,
args
,
i
),
MakeKey
(
g
,
args
,
i
));
if
(
!
(
str
=
Serialize
(
g
,
objp
,
NULL
,
0
)))
str
=
strcpy
(
result
,
g
->
Message
);
*
res_length
=
strlen
(
str
);
return
str
;
}
// end of Json_Object
void
Json_Object_deinit
(
UDF_INIT
*
initid
)
{
PlugExit
((
PGLOBAL
)
initid
->
ptr
);
}
// end of Json_Object_deinit
/***********************************************************************/
/* Make a Json array from values comming from rows. */
/***********************************************************************/
my_bool
Json_Array_Grp_init
(
UDF_INIT
*
initid
,
UDF_ARGS
*
args
,
char
*
message
)
{
unsigned
long
reslen
,
memlen
,
n
=
10
;
if
(
args
->
arg_count
!=
1
)
{
strcpy
(
message
,
"Json_Array_Grp can only accept 1 argument"
);
return
true
;
}
else
CalcLen
(
args
,
false
,
reslen
,
memlen
);
reslen
*=
n
;
memlen
*=
n
;
if
(
JsonInit
(
initid
,
message
,
reslen
,
memlen
))
return
true
;
PGLOBAL
g
=
(
PGLOBAL
)
initid
->
ptr
;
PlugSubSet
(
g
,
g
->
Sarea
,
g
->
Sarea_Size
);
g
->
Activityp
=
(
PACTIVITY
)
new
(
g
)
JARRAY
;
return
false
;
}
// end of Json_Array_Grp_init
void
Json_Array_Grp_add
(
UDF_INIT
*
initid
,
UDF_ARGS
*
args
,
char
*
is_null
,
char
*
error
)
{
PGLOBAL
g
=
(
PGLOBAL
)
initid
->
ptr
;
PJAR
arp
=
(
PJAR
)
g
->
Activityp
;
arp
->
AddValue
(
g
,
MakeValue
(
g
,
args
,
0
));
}
// end of Json_Array_Grp_add
char
*
Json_Array_Grp
(
UDF_INIT
*
initid
,
UDF_ARGS
*
args
,
char
*
result
,
unsigned
long
*
res_length
,
char
*
is_null
,
char
*
error
)
{
char
*
str
;
PGLOBAL
g
=
(
PGLOBAL
)
initid
->
ptr
;
PJAR
arp
=
(
PJAR
)
g
->
Activityp
;
arp
->
InitArray
(
g
);
if
(
!
(
str
=
Serialize
(
g
,
arp
,
NULL
,
0
)))
str
=
strcpy
(
result
,
g
->
Message
);
*
res_length
=
strlen
(
str
);
return
str
;
}
// end of Json_Array_Grp
void
Json_Array_Grp_clear
(
UDF_INIT
*
initid
,
char
*
is_null
,
char
*
error
)
{
PGLOBAL
g
=
(
PGLOBAL
)
initid
->
ptr
;
PlugSubSet
(
g
,
g
->
Sarea
,
g
->
Sarea_Size
);
g
->
Activityp
=
(
PACTIVITY
)
new
(
g
)
JARRAY
;
}
// end of Json_Array_Grp_clear
void
Json_Array_Grp_deinit
(
UDF_INIT
*
initid
)
{
PlugExit
((
PGLOBAL
)
initid
->
ptr
);
}
// end of Json_Array_Grp_deinit
/***********************************************************************/
/* Make a Json object from values comming from rows. */
/***********************************************************************/
my_bool
Json_Object_Grp_init
(
UDF_INIT
*
initid
,
UDF_ARGS
*
args
,
char
*
message
)
{
unsigned
long
reslen
,
memlen
,
n
=
10
;
if
(
args
->
arg_count
!=
2
)
{
strcpy
(
message
,
"Json_Array_Grp can only accept 2 argument"
);
return
true
;
}
else
CalcLen
(
args
,
true
,
reslen
,
memlen
);
reslen
*=
n
;
memlen
*=
n
;
if
(
JsonInit
(
initid
,
message
,
reslen
,
memlen
))
return
true
;
PGLOBAL
g
=
(
PGLOBAL
)
initid
->
ptr
;
PlugSubSet
(
g
,
g
->
Sarea
,
g
->
Sarea_Size
);
g
->
Activityp
=
(
PACTIVITY
)
new
(
g
)
JOBJECT
;
return
false
;
}
// end of Json_Object_Grp_init
void
Json_Object_Grp_add
(
UDF_INIT
*
initid
,
UDF_ARGS
*
args
,
char
*
is_null
,
char
*
error
)
{
PGLOBAL
g
=
(
PGLOBAL
)
initid
->
ptr
;
PJOB
objp
=
(
PJOB
)
g
->
Activityp
;
objp
->
SetValue
(
g
,
MakeValue
(
g
,
args
,
0
),
MakePSZ
(
g
,
args
,
1
));
}
// end of Json_Object_Grp_add
char
*
Json_Object_Grp
(
UDF_INIT
*
initid
,
UDF_ARGS
*
args
,
char
*
result
,
unsigned
long
*
res_length
,
char
*
is_null
,
char
*
error
)
{
char
*
str
;
PGLOBAL
g
=
(
PGLOBAL
)
initid
->
ptr
;
PJOB
objp
=
(
PJOB
)
g
->
Activityp
;
if
(
!
(
str
=
Serialize
(
g
,
objp
,
NULL
,
0
)))
str
=
strcpy
(
result
,
g
->
Message
);
*
res_length
=
strlen
(
str
);
return
str
;
}
// end of Json_Object_Grp
void
Json_Object_Grp_clear
(
UDF_INIT
*
initid
,
char
*
is_null
,
char
*
error
)
{
PGLOBAL
g
=
(
PGLOBAL
)
initid
->
ptr
;
PlugSubSet
(
g
,
g
->
Sarea
,
g
->
Sarea_Size
);
g
->
Activityp
=
(
PACTIVITY
)
new
(
g
)
JOBJECT
;
}
// end of Json_Object_Grp_clear
void
Json_Object_Grp_deinit
(
UDF_INIT
*
initid
)
{
PlugExit
((
PGLOBAL
)
initid
->
ptr
);
}
// end of Json_Object_Grp_deinit
storage/connect/myconn.cpp
View file @
56114a41
...
...
@@ -51,7 +51,8 @@
#define DLL_EXPORT // Items are exported from this DLL
#include "myconn.h"
extern
"C"
int
zconv
;
//extern "C" int zconv;
int
GetConvSize
(
void
);
extern
MYSQL_PLUGIN_IMPORT
uint
mysqld_port
;
extern
MYSQL_PLUGIN_IMPORT
char
*
mysqld_unix_port
;
...
...
@@ -265,7 +266,7 @@ PQRYRES MyColumns(PGLOBAL g, THD *thd, const char *host, const char *db,
return
NULL
;
}
else
if
(
type
==
TYPE_STRING
)
{
if
(
v
==
'X'
)
{
len
=
zconv
;
len
=
GetConvSize
()
;
sprintf
(
g
->
Message
,
"Column %s converted to varchar(%d)"
,
colname
,
len
);
PushWarning
(
g
,
thd
);
...
...
storage/connect/mysql-test/connect/r/json.result
View file @
56114a41
...
...
@@ -89,8 +89,8 @@ ISBN Language Subject AuthorFN AuthorLN Title Translation Translator Publisher L
UPDATE t1 SET AuthorFN = 'Philippe' WHERE AuthorLN = 'Knab';
SELECT * FROM t1 WHERE ISBN = '9782212090819';
ISBN Language Subject AuthorFN AuthorLN Title Translation Translator Publisher Location Year
9782212090819 fr applications
Jean-Christoph
e Bernadac Construire une application XML Eyrolles Paris 1999
9782212090819 fr applications
Philippe
Knab Construire une application XML Eyrolles Paris 1999
9782212090819 fr applications
Philipp
e Bernadac Construire une application XML Eyrolles Paris 1999
9782212090819 fr applications
Franois
Knab Construire une application XML Eyrolles Paris 1999
#
# To add an author a new table must be created
#
...
...
@@ -104,8 +104,8 @@ William J. Pardi
INSERT INTO t2 VALUES('Charles','Dickens');
SELECT * FROM t1;
ISBN Language Subject AuthorFN AuthorLN Title Translation Translator Publisher Location Year
9782212090819 fr applications
Jean-Christoph
e Bernadac Construire une application XML Eyrolles Paris 1999
9782212090819 fr applications
Philippe
Knab Construire une application XML Eyrolles Paris 1999
9782212090819 fr applications
Philipp
e Bernadac Construire une application XML Eyrolles Paris 1999
9782212090819 fr applications
Franois
Knab Construire une application XML Eyrolles Paris 1999
9782840825685 fr applications William J. Pardi XML en Action adapt de l'anglais par James Guerin Microsoft Press Paris 1999
9782840825685 fr applications Charles Dickens XML en Action adapt de l'anglais par James Guerin Microsoft Press Paris 1999
DROP TABLE t1;
...
...
@@ -127,11 +127,11 @@ line
"SUBJECT": "applications",
"AUTHOR": [
{
"FIRSTNAME": "
Jean-Christoph
e",
"FIRSTNAME": "
Philipp
e",
"LASTNAME": "Bernadac"
},
{
"FIRSTNAME": "
Philippe
",
"FIRSTNAME": "
Franois
",
"LASTNAME": "Knab"
}
],
...
...
@@ -192,7 +192,7 @@ Janet 4 Car 17.00
Janet 5 Beer+Car+Beer+Food 57.00
DROP TABLE t1;
#
#
Cannot
be fully expanded
#
Now it can
be fully expanded
#
CREATE TABLE t1 (
WHO CHAR(12),
...
...
@@ -201,7 +201,31 @@ WHAT CHAR(32) FIELD_FORMAT='WEEK:[X]:EXPENSE:[X]:WHAT',
AMOUNT DOUBLE(8,2) FIELD_FORMAT='WEEK:[X]:EXPENSE:[X]:AMOUNT')
ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='expense.jsn';
SELECT * FROM t1;
ERROR HY000: Got error 174 'Cannot expand more than one array' from CONNECT
WHO WEEK WHAT AMOUNT
Joe 3 Beer 18.00
Joe 3 Food 12.00
Joe 3 Food 19.00
Joe 3 Car 20.00
Joe 4 Beer 19.00
Joe 4 Beer 16.00
Joe 4 Food 17.00
Joe 4 Food 17.00
Joe 4 Beer 14.00
Joe 5 Beer 14.00
Joe 5 Food 12.00
Beth 3 Beer 16.00
Beth 4 Food 17.00
Beth 4 Beer 15.00
Beth 5 Food 12.00
Beth 5 Beer 20.00
Janet 3 Car 19.00
Janet 3 Food 18.00
Janet 3 Beer 18.00
Janet 4 Car 17.00
Janet 5 Beer 14.00
Janet 5 Car 12.00
Janet 5 Beer 19.00
Janet 5 Food 12.00
DROP TABLE t1;
#
# Expand expense in 3 one week tables
...
...
storage/connect/mysql-test/connect/t/json.test
View file @
56114a41
...
...
@@ -128,7 +128,7 @@ SELECT * FROM t1;
DROP
TABLE
t1
;
--
echo
#
--
echo
#
Cannot
be fully expanded
--
echo
#
Now it can
be fully expanded
--
echo
#
CREATE
TABLE
t1
(
WHO
CHAR
(
12
),
...
...
@@ -136,7 +136,7 @@ WEEK INT(2) FIELD_FORMAT='WEEK:[X]:NUMBER',
WHAT
CHAR
(
32
)
FIELD_FORMAT
=
'WEEK:[X]:EXPENSE:[X]:WHAT'
,
AMOUNT
DOUBLE
(
8
,
2
)
FIELD_FORMAT
=
'WEEK:[X]:EXPENSE:[X]:AMOUNT'
)
ENGINE
=
CONNECT
TABLE_TYPE
=
JSON
FILE_NAME
=
'expense.jsn'
;
--
error
ER_GET_ERRMSG
#
--error ER_GET_ERRMSG
SELECT
*
FROM
t1
;
DROP
TABLE
t1
;
...
...
storage/connect/myutil.cpp
View file @
56114a41
...
...
@@ -26,7 +26,8 @@
#include "myutil.h"
#define DLL_EXPORT // Items are exported from this DLL
extern
"C"
int
xconv
;
//extern "C" int xconv;
TYPCONV
GetTypeConv
(
void
);
/************************************************************************/
/* Convert from MySQL type name to PlugDB type number */
...
...
@@ -34,6 +35,7 @@ extern "C" int xconv;
int
MYSQLtoPLG
(
char
*
typname
,
char
*
var
)
{
int
type
;
TYPCONV
xconv
=
GetTypeConv
();
if
(
!
stricmp
(
typname
,
"int"
)
||
!
stricmp
(
typname
,
"mediumint"
)
||
!
stricmp
(
typname
,
"integer"
))
...
...
@@ -57,13 +59,13 @@ int MYSQLtoPLG(char *typname, char *var)
type
=
TYPE_TINY
;
else
if
(
!
stricmp
(
typname
,
"text"
)
&&
var
)
{
switch
(
xconv
)
{
case
1
:
case
TPC_YES
:
type
=
TYPE_STRING
;
*
var
=
'X'
;
break
;
case
2
:
case
TPC_SKIP
:
*
var
=
'K'
;
default:
default:
// TPC_NO
type
=
TYPE_ERROR
;
}
// endswitch xconv
...
...
@@ -88,7 +90,7 @@ int MYSQLtoPLG(char *typname, char *var)
}
else
if
(
type
==
TYPE_STRING
&&
!
stricmp
(
typname
,
"varchar"
))
// This is to make the difference between CHAR and VARCHAR
*
var
=
'V'
;
else
if
(
type
==
TYPE_ERROR
&&
xconv
==
2
)
else
if
(
type
==
TYPE_ERROR
&&
xconv
==
TPC_SKIP
)
*
var
=
'K'
;
else
*
var
=
0
;
...
...
@@ -174,7 +176,7 @@ const char *PLGtoMYSQLtype(int type, bool dbf, char v)
/************************************************************************/
int
MYSQLtoPLG
(
int
mytype
,
char
*
var
)
{
int
type
;
int
type
,
xconv
=
GetTypeConv
()
;
switch
(
mytype
)
{
case
MYSQL_TYPE_SHORT
:
...
...
@@ -221,7 +223,7 @@ int MYSQLtoPLG(int mytype, char *var)
case
MYSQL_TYPE_LONG_BLOB
:
if
(
var
)
{
switch
(
xconv
)
{
case
1
:
case
TPC_YES
:
if
(
*
var
!=
'B'
)
{
// This is a TEXT column
type
=
TYPE_STRING
;
...
...
@@ -230,9 +232,9 @@ int MYSQLtoPLG(int mytype, char *var)
type
=
TYPE_ERROR
;
break
;
case
2
:
case
TPC_SKIP
:
*
var
=
'K'
;
// Skip
default:
default:
// TPC_NO
type
=
TYPE_ERROR
;
}
// endswitch xconv
...
...
storage/connect/odbccat.h
View file @
56114a41
...
...
@@ -2,6 +2,14 @@
#define DEFAULT_LOGIN_TIMEOUT -1 // means do not set
#define DEFAULT_QUERY_TIMEOUT -1 // means do not set
typedef
struct
odbc_parms
{
char
*
User
;
// User connect info
char
*
Pwd
;
// Password connect info
int
Cto
;
// Connect timeout
int
Qto
;
// Query timeout
bool
UseCnc
;
// Use SQLConnect (!SQLDriverConnect)
}
ODBCPARM
,
*
POPARM
;
/***********************************************************************/
/* ODBC catalog function prototypes. */
/***********************************************************************/
...
...
@@ -10,8 +18,8 @@ char *ODBCCheckConnection(PGLOBAL g, char *dsn, int cop);
#endif // PROMPT_OK
PQRYRES
ODBCDataSources
(
PGLOBAL
g
,
int
maxres
,
bool
info
);
PQRYRES
ODBCColumns
(
PGLOBAL
g
,
char
*
dsn
,
char
*
db
,
char
*
table
,
char
*
colpat
,
int
maxres
,
int
cto
,
int
qto
,
bool
info
);
PQRYRES
ODBCSrcCols
(
PGLOBAL
g
,
char
*
dsn
,
char
*
src
,
int
cto
,
int
qto
);
char
*
colpat
,
int
maxres
,
bool
info
,
POPARM
sop
);
PQRYRES
ODBCSrcCols
(
PGLOBAL
g
,
char
*
dsn
,
char
*
src
,
POPARM
sop
);
PQRYRES
ODBCTables
(
PGLOBAL
g
,
char
*
dsn
,
char
*
db
,
char
*
tabpat
,
int
maxres
,
int
cto
,
int
qto
,
bool
info
);
int
maxres
,
bool
info
,
POPARM
sop
);
PQRYRES
ODBCDrivers
(
PGLOBAL
g
,
int
maxres
,
bool
info
);
storage/connect/odbconn.cpp
View file @
56114a41
...
...
@@ -37,8 +37,8 @@
#include "xobject.h"
//#include "kindex.h"
#include "xtable.h"
#include "tabodbc.h"
#include "odbccat.h"
#include "tabodbc.h"
#include "plgcnx.h" // For DB types
#include "resource.h"
#include "valblk.h"
...
...
@@ -53,6 +53,8 @@
extern
"C"
HINSTANCE
s_hModule
;
// Saved module handle
#endif // WIN32
int
GetConvSize
();
/***********************************************************************/
/* Some macro's (should be defined elsewhere to be more accessible) */
/***********************************************************************/
...
...
@@ -122,7 +124,7 @@ int TranslateSQLType(int stp, int prec, int& len, char& v)
case
SQL_LONGVARCHAR
:
// (-1)
v
=
'V'
;
type
=
TYPE_STRING
;
len
=
MY_MIN
(
abs
(
len
),
256
);
len
=
MY_MIN
(
abs
(
len
),
GetConvSize
()
);
break
;
case
SQL_NUMERIC
:
// 2
case
SQL_DECIMAL
:
// 3
...
...
@@ -291,7 +293,7 @@ static void ResetNullValues(CATPARM *cap)
/* of an ODBC table that will be retrieved by GetData commands. */
/***********************************************************************/
PQRYRES
ODBCColumns
(
PGLOBAL
g
,
char
*
dsn
,
char
*
db
,
char
*
table
,
char
*
colpat
,
int
maxres
,
int
cto
,
int
qto
,
bool
info
)
char
*
colpat
,
int
maxres
,
bool
info
,
POPARM
sop
)
{
int
buftyp
[]
=
{
TYPE_STRING
,
TYPE_STRING
,
TYPE_STRING
,
TYPE_STRING
,
TYPE_SHORT
,
TYPE_STRING
,
TYPE_INT
,
TYPE_INT
,
...
...
@@ -310,10 +312,8 @@ PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *db, char *table,
/************************************************************************/
if
(
!
info
)
{
ocp
=
new
(
g
)
ODBConn
(
g
,
NULL
);
ocp
->
SetLoginTimeout
((
DWORD
)
cto
);
ocp
->
SetQueryTimeout
((
DWORD
)
qto
);
if
(
ocp
->
Open
(
dsn
,
10
)
<
1
)
// openReadOnly + noODBCdialog
if
(
ocp
->
Open
(
dsn
,
sop
,
10
)
<
1
)
// openReadOnly + noODBCdialog
return
NULL
;
if
(
table
&&
!
strchr
(
table
,
'%'
))
{
...
...
@@ -342,7 +342,7 @@ PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *db, char *table,
}
// endif ocp
if
(
trace
)
htrc
(
"ODBCColumns: max=%d len=%d,%d,%d
\n
"
,
htrc
(
"ODBCColumns: max=%d len=%d,%d,%d
,%d
\n
"
,
maxres
,
length
[
0
],
length
[
1
],
length
[
2
],
length
[
3
]);
/************************************************************************/
...
...
@@ -388,12 +388,13 @@ PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *db, char *table,
/* ODBCSrcCols: constructs the result blocks containing the */
/* description of all the columns of a Srcdef option. */
/**************************************************************************/
PQRYRES
ODBCSrcCols
(
PGLOBAL
g
,
char
*
dsn
,
char
*
src
,
int
cto
,
int
qto
)
PQRYRES
ODBCSrcCols
(
PGLOBAL
g
,
char
*
dsn
,
char
*
src
,
POPARM
sop
)
{
ODBConn
*
ocp
=
new
(
g
)
ODBConn
(
g
,
NULL
);
ocp
->
SetLoginTimeout
((
DWORD
)
cto
);
ocp
->
SetQueryTimeout
((
DWORD
)
qto
);
if
(
ocp
->
Open
(
dsn
,
sop
,
10
)
<
1
)
// openReadOnly + noOdbcDialog
return
NULL
;
return
ocp
->
GetMetaData
(
g
,
dsn
,
src
);
}
// end of ODBCSrcCols
...
...
@@ -574,7 +575,7 @@ PQRYRES ODBCDataSources(PGLOBAL g, int maxres, bool info)
/* an ODBC database that will be retrieved by GetData commands. */
/**************************************************************************/
PQRYRES
ODBCTables
(
PGLOBAL
g
,
char
*
dsn
,
char
*
db
,
char
*
tabpat
,
int
maxres
,
int
cto
,
int
qto
,
bool
info
)
int
maxres
,
bool
info
,
POPARM
sop
)
{
int
buftyp
[]
=
{
TYPE_STRING
,
TYPE_STRING
,
TYPE_STRING
,
TYPE_STRING
,
TYPE_STRING
};
...
...
@@ -594,10 +595,8 @@ PQRYRES ODBCTables(PGLOBAL g, char *dsn, char *db, char *tabpat,
/* Open the connection with the ODBC data source. */
/**********************************************************************/
ocp
=
new
(
g
)
ODBConn
(
g
,
NULL
);
ocp
->
SetLoginTimeout
((
DWORD
)
cto
);
ocp
->
SetQueryTimeout
((
DWORD
)
qto
);
if
(
ocp
->
Open
(
dsn
,
2
)
<
1
)
// 2 is openReadOnly
if
(
ocp
->
Open
(
dsn
,
sop
,
2
)
<
1
)
// 2 is openReadOnly
return
NULL
;
if
(
!
maxres
)
...
...
@@ -925,11 +924,14 @@ ODBConn::ODBConn(PGLOBAL g, TDBODBC *tdbp)
m_Catver
=
(
tdbp
)
?
tdbp
->
Catver
:
0
;
m_Rows
=
0
;
m_Connect
=
NULL
;
m_User
=
NULL
;
m_Pwd
=
NULL
;
m_Updatable
=
true
;
m_Transact
=
false
;
m_Scrollable
=
(
tdbp
)
?
tdbp
->
Scrollable
:
false
;
m_First
=
true
;
m_Full
=
false
;
m_UseCnc
=
false
;
m_IDQuoteChar
[
0
]
=
'"'
;
m_IDQuoteChar
[
1
]
=
0
;
//*m_ErrMsg = '\0';
...
...
@@ -1061,7 +1063,7 @@ void ODBConn::OnSetOptions(HSTMT hstmt)
/***********************************************************************/
/* Open: connect to a data source. */
/***********************************************************************/
int
ODBConn
::
Open
(
PSZ
ConnectString
,
DWORD
options
)
int
ODBConn
::
Open
(
PSZ
ConnectString
,
POPARM
sop
,
DWORD
options
)
{
PGLOBAL
&
g
=
m_G
;
//ASSERT_VALID(this);
...
...
@@ -1070,6 +1072,11 @@ int ODBConn::Open(PSZ ConnectString, DWORD options)
m_Updatable
=
!
(
options
&
openReadOnly
);
m_Connect
=
ConnectString
;
m_User
=
sop
->
User
;
m_Pwd
=
sop
->
Pwd
;
m_LoginTimeout
=
sop
->
Cto
;
m_QueryTimeout
=
sop
->
Qto
;
m_UseCnc
=
sop
->
UseCnc
;
// Allocate the HDBC and make connection
try
{
...
...
@@ -1078,11 +1085,15 @@ int ODBConn::Open(PSZ ConnectString, DWORD options)
AllocConnect
(
options
);
/*ver = GetStringInfo(SQL_ODBC_VER);*/
if
(
Connect
(
options
))
{
if
(
!
m_UseCnc
)
{
if
(
DriverConnect
(
options
))
{
strcpy
(
g
->
Message
,
MSG
(
CONNECT_CANCEL
));
return
0
;
}
// endif
}
else
// Connect using SQLConnect
Connect
();
/*ver = GetStringInfo(SQL_DRIVER_ODBC_VER);*/
// Verify support for required functionality and cache info
// VerifyConnect(); Deprecated
...
...
@@ -1163,10 +1174,27 @@ void ODBConn::AllocConnect(DWORD Options)
return
;
}
// end of AllocConnect
/***********************************************************************/
/* Connect to data source using SQLConnect. */
/***********************************************************************/
void
ODBConn
::
Connect
(
void
)
{
SQLRETURN
rc
;
SQLSMALLINT
ul
=
(
m_User
?
SQL_NTS
:
0
);
SQLSMALLINT
pl
=
(
m_Pwd
?
SQL_NTS
:
0
);
rc
=
SQLConnect
(
m_hdbc
,
(
SQLCHAR
*
)
m_Connect
,
SQL_NTS
,
(
SQLCHAR
*
)
m_User
,
ul
,
(
SQLCHAR
*
)
m_Pwd
,
pl
);
if
(
!
Check
(
rc
))
ThrowDBX
(
rc
,
"SQLConnect"
);
}
// end of Connect
/***********************************************************************/
/* Connect to data source using SQLDriverConnect. */
/***********************************************************************/
bool
ODBConn
::
Connect
(
DWORD
Options
)
bool
ODBConn
::
Driver
Connect
(
DWORD
Options
)
{
RETCODE
rc
;
SWORD
nResult
;
...
...
@@ -1213,7 +1241,7 @@ bool ODBConn::Connect(DWORD Options)
// All done
return
false
;
}
// end of Connect
}
// end of
Driver
Connect
void
ODBConn
::
VerifyConnect
()
{
...
...
@@ -1712,6 +1740,8 @@ bool ODBConn::BindParam(ODBCCOL *colp)
strcpy
(
m_G
->
Message
,
x
->
GetErrorMessage
(
0
));
colsize
=
colp
->
GetPrecision
();
sqlt
=
GetSQLType
(
buftype
);
dec
=
IsTypeChar
(
buftype
)
?
0
:
colp
->
GetScale
();
nul
=
SQL_NULLABLE_UNKNOWN
;
}
// end try/catch
buf
=
colp
->
GetBuffer
(
0
);
...
...
@@ -1865,9 +1895,6 @@ PQRYRES ODBConn::GetMetaData(PGLOBAL g, char *dsn, char *src)
RETCODE
rc
;
HSTMT
hstmt
;
if
(
Open
(
dsn
,
10
)
<
1
)
// openReadOnly + noOdbcDialog
return
NULL
;
try
{
rc
=
SQLAllocStmt
(
m_hdbc
,
&
hstmt
);
...
...
storage/connect/odbconn.h
View file @
56114a41
...
...
@@ -119,7 +119,7 @@ class ODBConn : public BLOCK {
noOdbcDialog
=
0x0008
,
// Don't display ODBC Connect dialog
forceOdbcDialog
=
0x0010
};
// Always display ODBC connect dialog
int
Open
(
PSZ
ConnectString
,
DWORD
Options
=
0
);
int
Open
(
PSZ
ConnectString
,
POPARM
sop
,
DWORD
Options
=
0
);
int
Rewind
(
char
*
sql
,
ODBCCOL
*
tocols
);
void
Close
(
void
);
PQRYRES
AllocateResult
(
PGLOBAL
g
);
...
...
@@ -135,8 +135,10 @@ class ODBConn : public BLOCK {
public:
// Operations
void
SetLoginTimeout
(
DWORD
sec
)
{
m_LoginTimeout
=
sec
;}
void
SetQueryTimeout
(
DWORD
sec
)
{
m_QueryTimeout
=
sec
;}
//void SetLoginTimeout(DWORD sec) {m_LoginTimeout = sec;}
//void SetQueryTimeout(DWORD sec) {m_QueryTimeout = sec;}
//void SetUserName(PSZ user) {m_User = user;}
//void SetUserPwd(PSZ pwd) {m_Pwd = pwd;}
int
GetResultSize
(
char
*
sql
,
ODBCCOL
*
colp
);
int
ExecDirectSQL
(
char
*
sql
,
ODBCCOL
*
tocols
);
int
Fetch
(
void
);
...
...
@@ -155,7 +157,7 @@ class ODBConn : public BLOCK {
// Implementation
public:
//
virtual ~ODBConn();
//virtual ~ODBConn();
// ODBC operations
protected:
...
...
@@ -163,7 +165,8 @@ class ODBConn : public BLOCK {
void
ThrowDBX
(
RETCODE
rc
,
PSZ
msg
,
HSTMT
hstmt
=
SQL_NULL_HSTMT
);
void
ThrowDBX
(
PSZ
msg
);
void
AllocConnect
(
DWORD
dwOptions
);
bool
Connect
(
DWORD
Options
);
void
Connect
(
void
);
bool
DriverConnect
(
DWORD
Options
);
void
VerifyConnect
(
void
);
void
GetConnectInfo
(
void
);
void
Free
(
void
);
...
...
@@ -185,11 +188,14 @@ class ODBConn : public BLOCK {
DWORD
m_RowsetSize
;
char
m_IDQuoteChar
[
2
];
PSZ
m_Connect
;
PSZ
m_User
;
PSZ
m_Pwd
;
int
m_Catver
;
int
m_Rows
;
bool
m_Updatable
;
bool
m_Transact
;
bool
m_Scrollable
;
bool
m_UseCnc
;
bool
m_First
;
bool
m_Full
;
};
// end of ODBConn class definition
storage/connect/tabdos.h
View file @
56114a41
...
...
@@ -222,6 +222,7 @@ class DllExport DOSCOL : public COLBLK {
virtual
PVBLK
GetDval
(
void
)
{
return
Dval
;}
// Methods
using
COLBLK
::
Print
;
virtual
bool
VarSize
(
void
);
virtual
bool
SetBuffer
(
PGLOBAL
g
,
PVAL
value
,
bool
ok
,
bool
check
);
virtual
void
ReadColumn
(
PGLOBAL
g
);
...
...
storage/connect/tabjson.cpp
View file @
56114a41
/************* tabjson C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: tab
xjson Version 1.0
*/
/* PROGRAM NAME: tab
json Version 1.0
*/
/* (C) Copyright to the author Olivier BERTRAND 2014 - 2015 */
/* This program are the JSON class DB execution routines. */
/***********************************************************************/
...
...
@@ -119,12 +119,12 @@ TDBJSN::TDBJSN(PJDEF tdp, PTXF txfp) : TDBDOS(tdp, txfp)
Fpos
=
-
1
;
Spos
=
N
=
0
;
Limit
=
tdp
->
Limit
;
NextSame
=
0
;
SameRow
=
0
;
Xval
=
-
1
;
Pretty
=
tdp
->
Pretty
;
Strict
=
tdp
->
Strict
;
NextSame
=
false
;
Comma
=
false
;
SameRow
=
0
;
Xval
=
-
1
;
}
// end of TDBJSN standard constructor
TDBJSN
::
TDBJSN
(
TDBJSN
*
tdbp
)
:
TDBDOS
(
NULL
,
tdbp
)
...
...
@@ -137,12 +137,12 @@ TDBJSN::TDBJSN(TDBJSN *tdbp) : TDBDOS(NULL, tdbp)
Spos
=
tdbp
->
Spos
;
N
=
tdbp
->
N
;
Limit
=
tdbp
->
Limit
;
Pretty
=
tdbp
->
Pretty
;
Strict
=
tdbp
->
Strict
;
NextSame
=
tdbp
->
NextSame
;
Comma
=
tdbp
->
Comma
;
SameRow
=
tdbp
->
SameRow
;
Xval
=
tdbp
->
Xval
;
Pretty
=
tdbp
->
Pretty
;
Strict
=
tdbp
->
Strict
;
Comma
=
tdbp
->
Comma
;
}
// end of TDBJSN copy constructor
// Used for update
...
...
@@ -221,14 +221,9 @@ bool TDBJSN::OpenDB(PGLOBAL g)
/*******************************************************************/
/* Table already open replace it at its beginning. */
/*******************************************************************/
for
(
PJCOL
cp
=
(
PJCOL
)
Columns
;
cp
;
cp
=
(
PJCOL
)
cp
->
GetNext
())
{
cp
->
Nx
=
0
;
cp
->
Arp
=
NULL
;
}
// endfor cp
Fpos
=
-
1
;
Spos
=
0
;
NextSame
=
false
;
NextSame
=
0
;
SameRow
=
0
;
}
else
{
/*******************************************************************/
...
...
@@ -292,7 +287,8 @@ int TDBJSN::ReadDB(PGLOBAL g)
N
++
;
if
(
NextSame
)
{
SameRow
++
;
SameRow
=
NextSame
;
NextSame
=
0
;
return
RC_OK
;
}
else
if
((
rc
=
TDBDOS
::
ReadDB
(
g
))
==
RC_OK
)
if
(
!
IsRead
()
&&
((
rc
=
ReadBuffer
(
g
))
!=
RC_OK
))
{
...
...
@@ -333,21 +329,20 @@ int TDBJSN::ReadDB(PGLOBAL g)
}
// end of PrepareWriting
/* ----------------------------
- JSNCOL -
------------------------------ */
/* ----------------------------
JSONCOL
------------------------------ */
/***********************************************************************/
/* JS
NCOL public constructor.
*/
/* JS
ONCOL public constructor.
*/
/***********************************************************************/
JSONCOL
::
JSONCOL
(
PGLOBAL
g
,
PCOLDEF
cdp
,
PTDB
tdbp
,
PCOL
cprec
,
int
i
)
:
DOSCOL
(
g
,
cdp
,
tdbp
,
cprec
,
i
,
"DOS"
)
{
Tjp
=
(
TDBJSN
*
)(
tdbp
->
GetOrig
()
?
tdbp
->
GetOrig
()
:
tdbp
);
Arp
=
NULL
;
Jpath
=
cdp
->
GetFmt
();
MulVal
=
NULL
;
Nodes
=
NULL
;
Nod
=
Nx
=
0
;
Ival
=
-
1
;
Nod
=
0
;
Xnod
=
-
1
;
Xpd
=
false
;
Parsed
=
false
;
}
// end of JSONCOL constructor
...
...
@@ -359,13 +354,11 @@ JSONCOL::JSONCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i)
JSONCOL
::
JSONCOL
(
JSONCOL
*
col1
,
PTDB
tdbp
)
:
DOSCOL
(
col1
,
tdbp
)
{
Tjp
=
col1
->
Tjp
;
Arp
=
col1
->
Arp
;
Jpath
=
col1
->
Jpath
;
MulVal
=
col1
->
MulVal
;
Nodes
=
col1
->
Nodes
;
Nod
=
col1
->
Nod
;
Ival
=
col1
->
Ival
;
Nx
=
col1
->
Nx
;
Xnod
=
col1
->
Xnod
;
Xpd
=
col1
->
Xpd
;
Parsed
=
col1
->
Parsed
;
}
// end of JSONCOL copy constructor
...
...
@@ -387,17 +380,16 @@ bool JSONCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check)
}
// end of SetBuffer
/***********************************************************************/
/*
Analyse array processing options.
*/
/*
Check whether this object is expanded.
*/
/***********************************************************************/
bool
JSONCOL
::
CheckExpand
(
PGLOBAL
g
,
int
i
,
PSZ
nm
,
bool
b
)
{
if
(
Tjp
->
Xcol
&&
nm
&&
!
strcmp
(
nm
,
Tjp
->
Xcol
)
&&
(
Tjp
->
Xval
<
0
||
Tjp
->
Xval
==
i
)
)
{
if
(
(
Tjp
->
Xcol
&&
nm
&&
!
strcmp
(
nm
,
Tjp
->
Xcol
)
&&
(
Tjp
->
Xval
<
0
||
Tjp
->
Xval
==
i
))
||
Xpd
)
{
Xpd
=
true
;
// Expandable object
Nodes
[
i
].
Op
=
OP_XX
;
Tjp
->
Xval
=
i
;
Nodes
[
i
].
Op
=
OP_EXP
;
}
else
if
(
b
)
{
strcpy
(
g
->
Message
,
"Cannot expand more than one
array
"
);
strcpy
(
g
->
Message
,
"Cannot expand more than one
branch
"
);
return
true
;
}
// endif Xcol
...
...
@@ -434,7 +426,7 @@ bool JSONCOL::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm)
// Default specifications
if
(
CheckExpand
(
g
,
i
,
nm
,
false
))
return
true
;
else
if
(
jnp
->
Op
!=
OP_
XX
)
else
if
(
jnp
->
Op
!=
OP_
EXP
)
if
(
!
Value
->
IsTypeNum
())
{
jnp
->
CncVal
=
AllocateValue
(
g
,
(
void
*
)
", "
,
TYPE_STRING
);
jnp
->
Op
=
OP_CNC
;
...
...
@@ -456,13 +448,13 @@ bool JSONCOL::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm)
case
'*'
:
jnp
->
Op
=
OP_MULT
;
break
;
case
'>'
:
jnp
->
Op
=
OP_MAX
;
break
;
case
'<'
:
jnp
->
Op
=
OP_MIN
;
break
;
case
'#'
:
jnp
->
Op
=
OP_NUM
;
break
;
case
'!'
:
jnp
->
Op
=
OP_SEP
;
break
;
// Average
case
'#'
:
jnp
->
Op
=
OP_NUM
;
break
;
case
'x'
:
case
'X'
:
// Expand this array
if
(
!
Tjp
->
Xcol
&&
nm
)
{
Xpd
=
true
;
jnp
->
Op
=
OP_
XX
;
jnp
->
Op
=
OP_
EXP
;
Tjp
->
Xval
=
i
;
Tjp
->
Xcol
=
nm
;
}
else
if
(
CheckExpand
(
g
,
i
,
nm
,
true
))
...
...
@@ -490,6 +482,38 @@ bool JSONCOL::SetArrayOptions(PGLOBAL g, char *p, int i, PSZ nm)
return
true
;
}
// endif's
// For calculated arrays, a local Value must be used
switch
(
jnp
->
Op
)
{
case
OP_NUM
:
jnp
->
Valp
=
AllocateValue
(
g
,
TYPE_INT
);
break
;
case
OP_ADD
:
case
OP_MULT
:
case
OP_SEP
:
if
(
!
IsTypeChar
(
Buf_Type
))
jnp
->
Valp
=
AllocateValue
(
g
,
Buf_Type
,
0
,
GetPrecision
());
else
jnp
->
Valp
=
AllocateValue
(
g
,
TYPE_DOUBLE
);
break
;
case
OP_MIN
:
case
OP_MAX
:
jnp
->
Valp
=
AllocateValue
(
g
,
Buf_Type
,
Long
,
GetPrecision
());
break
;
case
OP_CNC
:
if
(
IsTypeChar
(
Buf_Type
))
jnp
->
Valp
=
AllocateValue
(
g
,
TYPE_STRING
,
Long
,
GetPrecision
());
else
jnp
->
Valp
=
AllocateValue
(
g
,
TYPE_STRING
,
512
);
break
;
default:
break
;
}
// endswitch Op
if
(
jnp
->
Valp
)
MulVal
=
AllocateValue
(
g
,
jnp
->
Valp
);
return
false
;
}
// end of SetArrayOptions
...
...
@@ -533,6 +557,9 @@ bool JSONCOL::ParseJpath(PGLOBAL g)
if
(
SetArrayOptions
(
g
,
p
,
i
,
Nodes
[
i
-
1
].
Key
))
return
true
;
}
else
if
(
*
p
==
'*'
)
{
// Return JSON
Nodes
[
i
].
Op
=
OP_XX
;
}
else
{
Nodes
[
i
].
Key
=
p
;
Nodes
[
i
].
Op
=
OP_EXIST
;
...
...
@@ -545,16 +572,26 @@ bool JSONCOL::ParseJpath(PGLOBAL g)
return
false
;
}
// end of ParseJpath
/***********************************************************************/
/* MakeJson: Serialize the json item and set value to it. */
/***********************************************************************/
PVAL
JSONCOL
::
MakeJson
(
PGLOBAL
g
,
PJSON
jsp
)
{
if
(
Value
->
IsTypeNum
())
{
strcpy
(
g
->
Message
,
"Cannot make Json for a numeric column"
);
Value
->
Reset
();
}
else
Value
->
SetValue_psz
(
Serialize
(
g
,
jsp
,
NULL
,
0
));
return
Value
;
}
// end of MakeJson
/***********************************************************************/
/* SetValue: Set a value from a JVALUE contains. */
/***********************************************************************/
void
JSONCOL
::
SetJsonValue
(
PGLOBAL
g
,
PVAL
vp
,
PJVAL
val
,
int
n
)
{
if
(
val
)
{
if
(
Nodes
[
n
].
Op
==
OP_NUM
)
vp
->
SetValue
(
1
);
else
{
again:
switch
(
val
->
GetValType
())
{
case
TYPE_STRG
:
case
TYPE_INTG
:
...
...
@@ -569,68 +606,82 @@ void JSONCOL::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val, int n)
break
;
case
TYPE_JAR
:
val
=
val
->
GetArray
()
->
GetValue
(
0
);
goto
again
;
SetJsonValue
(
g
,
vp
,
val
->
GetArray
()
->
GetValue
(
0
),
n
);
break
;
case
TYPE_JOB
:
if
(
!
vp
->
IsTypeNum
()
)
{
// if (!vp->IsTypeNum() || !Strict
) {
vp
->
SetValue_psz
(
val
->
GetObject
()
->
GetText
(
g
));
break
;
}
// endif Type
//
} // endif Type
default:
vp
->
Reset
();
}
// endswitch Type
}
// endelse
}
else
vp
->
Reset
();
}
// end of SetJsonValue
/***********************************************************************/
/*
GetRow: Get the object containing this column.
*/
/*
ReadColumn:
*/
/***********************************************************************/
PJSON
JSONCOL
::
GetRow
(
PGLOBAL
g
,
int
mode
)
void
JSONCOL
::
ReadColumn
(
PGLOBAL
g
)
{
PJVAL
val
;
if
(
!
Tjp
->
SameRow
||
Xnod
>=
Tjp
->
SameRow
)
Value
->
SetValue_pval
(
GetColumnValue
(
g
,
Tjp
->
Row
,
0
));
}
// end of ReadColumn
/***********************************************************************/
/* GetColumnValue: */
/***********************************************************************/
PVAL
JSONCOL
::
GetColumnValue
(
PGLOBAL
g
,
PJSON
row
,
int
i
)
{
int
n
=
Nod
-
1
;
bool
expd
=
false
;
PJAR
arp
;
PJ
SON
nwr
,
row
=
Tjp
->
Row
;
PJ
VAL
val
=
NULL
;
for
(
int
i
=
0
;
i
<
Nod
-
1
&&
row
;
i
++
)
{
switch
(
row
->
GetType
())
{
for
(;
i
<
Nod
&&
row
;
i
++
)
{
if
(
Nodes
[
i
].
Op
==
OP_NUM
)
{
Value
->
SetValue
(
row
->
GetType
()
==
TYPE_JAR
?
row
->
size
()
:
1
);
return
(
Value
);
}
else
if
(
Nodes
[
i
].
Op
==
OP_XX
)
{
return
MakeJson
(
g
,
row
);
}
else
switch
(
row
->
GetType
())
{
case
TYPE_JOB
:
if
(
!
Nodes
[
i
].
Key
)
if
(
!
Nodes
[
i
].
Key
)
{
// Expected Array was not there
if
(
i
<
Nod
-
1
)
continue
;
else
val
=
new
(
g
)
JVALUE
(
row
);
}
else
val
=
((
PJOB
)
row
)
->
GetValue
(
Nodes
[
i
].
Key
);
break
;
case
TYPE_JAR
:
if
(
!
Nodes
[
i
].
Key
)
{
if
(
Nodes
[
i
].
Op
!=
OP_NULL
)
{
Ival
=
i
;
arp
=
(
PJAR
)
row
;
if
(
mode
<
2
)
// First pass
Arp
=
arp
;
if
(
Nodes
[
i
].
Op
!=
OP_XX
)
{
if
(
Nodes
[
i
].
Rank
)
if
(
!
Nodes
[
i
].
Key
)
{
if
(
Nodes
[
i
].
Op
!=
OP_NULL
)
{
if
(
Nodes
[
i
].
Rank
)
{
val
=
arp
->
GetValue
(
Nodes
[
i
].
Rank
-
1
);
else
val
=
arp
->
GetValue
(
arp
==
Arp
?
Nx
:
0
);
}
else
if
(
Nodes
[
i
].
Op
==
OP_EXP
)
{
return
ExpandArray
(
g
,
arp
,
i
);
}
else
val
=
arp
->
GetValue
(
Tjp
->
SameRow
);
return
CalculateArray
(
g
,
arp
,
i
);
}
else
val
=
NULL
;
}
else
{
}
else
if
(
i
<
Nod
-
1
)
{
strcpy
(
g
->
Message
,
"Unexpected array"
);
val
=
NULL
;
// Not an expected array
}
// endif Nodes
}
else
val
=
arp
->
GetValue
(
0
);
break
;
case
TYPE_JVAL
:
...
...
@@ -641,164 +692,209 @@ PJSON JSONCOL::GetRow(PGLOBAL g, int mode)
val
=
NULL
;
}
// endswitch Type
if
(
val
)
{
row
=
val
->
GetJson
();
}
else
if
(
mode
==
1
)
{
// mode write
// Construct missing objects
for
(
i
++
;
row
&&
i
<
Nod
;
i
++
)
{
if
(
!
Nodes
[
i
].
Key
)
{
// Construct intermediate array
nwr
=
new
(
g
)
JARRAY
;
}
else
{
nwr
=
new
(
g
)
JOBJECT
;
}
// endif Nodes
if
(
row
->
GetType
()
==
TYPE_JOB
)
{
((
PJOB
)
row
)
->
SetValue
(
g
,
new
(
g
)
JVALUE
(
nwr
),
Nodes
[
i
-
1
].
Key
);
}
else
if
(
row
->
GetType
()
==
TYPE_JAR
)
{
((
PJAR
)
row
)
->
AddValue
(
g
,
new
(
g
)
JVALUE
(
nwr
));
((
PJAR
)
row
)
->
InitArray
(
g
);
}
else
{
strcpy
(
g
->
Message
,
"Wrong type when writing new row"
);
nwr
=
NULL
;
}
// endif's
row
=
nwr
;
}
// endfor i
break
;
}
else
row
=
NULL
;
if
(
i
<
Nod
-
1
)
row
=
(
val
)
?
val
->
GetJson
()
:
NULL
;
}
// endfor i
return
row
;
}
// end of GetRow
SetJsonValue
(
g
,
Value
,
val
,
n
);
return
Value
;
}
// end of GetColumnValue
/***********************************************************************/
/*
ReadColumn:
*/
/*
ExpandArray:
*/
/***********************************************************************/
void
JSONCOL
::
ReadColumn
(
PGLOBAL
g
)
PVAL
JSONCOL
::
ExpandArray
(
PGLOBAL
g
,
PJAR
arp
,
int
n
)
{
int
mode
=
0
,
n
=
Nod
-
1
;
PJ
SON
row
;
PJVAL
val
=
NULL
;
int
ars
;
PJ
VAL
jvp
;
JVALUE
jval
;
evenmore:
row
=
GetRow
(
g
,
mode
);
ars
=
MY_MIN
(
Tjp
->
Limit
,
arp
->
size
());
more:
if
(
row
)
switch
(
row
->
GetType
())
{
case
TYPE_JOB
:
if
(
Nodes
[
n
].
Key
)
val
=
row
->
GetValue
(
Nodes
[
n
].
Key
);
else
val
=
new
(
g
)
JVALUE
(
row
);
if
(
!
(
jvp
=
arp
->
GetValue
(
Nodes
[
n
].
Nx
)))
{
strcpy
(
g
->
Message
,
"Logical error expanding array"
);
longjmp
(
g
->
jumper
[
g
->
jump_level
],
666
);
}
// endif jvp
break
;
case
TYPE_JAR
:
// Multiple column ?
if
(
Nodes
[
n
].
Op
!=
OP_NULL
)
{
Arp
=
(
PJAR
)
row
;
val
=
Arp
->
GetValue
(
Nodes
[
n
].
Rank
>
0
?
Nodes
[
n
].
Rank
-
1
:
Nodes
[
n
].
Op
==
OP_XX
?
Tjp
->
SameRow
:
Nx
)
;
Ival
=
n
;
if
(
n
<
Nod
-
1
&&
jvp
->
GetJson
())
{
jval
.
SetValue
(
GetColumnValue
(
g
,
jvp
->
GetJson
(),
n
+
1
));
jvp
=
&
jval
;
}
// endif n
if
(
n
>=
Tjp
->
NextSame
)
{
if
(
++
Nodes
[
n
].
Nx
==
ars
)
{
Nodes
[
n
].
Nx
=
0
;
Xnod
=
0
;
}
else
val
=
NULL
;
Xnod
=
n
;
break
;
case
TYPE_JVAL
:
val
=
(
PJVAL
)
row
;
break
;
default:
sprintf
(
g
->
Message
,
"Wrong return value type %d"
,
row
->
GetType
());
Value
->
Reset
();
return
;
}
// endswitch Type
Tjp
->
NextSame
=
Xnod
;
}
// endif NextSame
if
(
!
Nx
/*|| (Xpd)*/
)
SetJsonValue
(
g
,
Value
,
val
,
n
);
SetJsonValue
(
g
,
Value
,
jvp
,
n
);
return
Value
;
}
// end of ExpandArray
if
(
Arp
)
{
// Multiple column
int
ars
=
(
Nodes
[
Ival
].
Rank
>
0
)
?
1
:
MY_MIN
(
Tjp
->
Limit
,
Arp
->
size
());
/***********************************************************************/
/* CalculateArray: */
/***********************************************************************/
PVAL
JSONCOL
::
CalculateArray
(
PGLOBAL
g
,
PJAR
arp
,
int
n
)
{
int
i
,
ars
,
nv
=
0
,
nextsame
=
Tjp
->
NextSame
;
bool
err
;
OPVAL
op
=
Nodes
[
n
].
Op
;
PVAL
val
[
2
],
vp
=
Nodes
[
n
].
Valp
;
PJVAL
jvrp
,
jvp
;
JVALUE
jval
;
if
(
Nodes
[
Ival
].
Op
==
OP_XX
)
{
if
(
ars
>
Tjp
->
SameRow
+
1
)
Tjp
->
NextSame
=
true
;
// More to come
else
{
Tjp
->
NextSame
=
false
;
Arp
=
NULL
;
}
// endelse
vp
->
Reset
();
ars
=
MY_MIN
(
Tjp
->
Limit
,
arp
->
size
());
}
else
{
if
(
Nx
&&
val
)
{
SetJsonValue
(
g
,
MulVal
,
val
,
Ival
);
for
(
i
=
0
;
i
<
ars
;
i
++
)
{
jvrp
=
arp
->
GetValue
(
i
);
if
(
!
MulVal
->
IsZero
())
{
PVAL
val
[
2
];
bool
err
;
do
{
if
(
n
<
Nod
-
1
&&
jvrp
->
GetJson
())
{
Tjp
->
NextSame
=
nextsame
;
jval
.
SetValue
(
GetColumnValue
(
g
,
jvrp
->
GetJson
(),
n
+
1
));
jvp
=
&
jval
;
}
else
jvp
=
jvrp
;
if
(
!
nv
++
)
{
SetJsonValue
(
g
,
vp
,
jvp
,
n
);
continue
;
}
else
SetJsonValue
(
g
,
MulVal
,
jvp
,
n
);
switch
(
Nodes
[
Ival
].
Op
)
{
if
(
!
MulVal
->
IsZero
())
{
switch
(
op
)
{
case
OP_CNC
:
if
(
Nodes
[
Ival
].
CncVal
)
{
val
[
0
]
=
Nodes
[
Ival
].
CncVal
;
err
=
Value
->
Compute
(
g
,
val
,
1
,
Nodes
[
Ival
].
O
p
);
if
(
Nodes
[
n
].
CncVal
)
{
val
[
0
]
=
Nodes
[
n
].
CncVal
;
err
=
vp
->
Compute
(
g
,
val
,
1
,
o
p
);
}
// endif CncVal
val
[
0
]
=
MulVal
;
err
=
Value
->
Compute
(
g
,
val
,
1
,
Nodes
[
Ival
].
O
p
);
err
=
vp
->
Compute
(
g
,
val
,
1
,
o
p
);
break
;
case
OP_NUM
:
//
case OP_NUM:
case
OP_SEP
:
val
[
0
]
=
Value
;
val
[
0
]
=
Nodes
[
n
].
Valp
;
val
[
1
]
=
MulVal
;
err
=
Value
->
Compute
(
g
,
val
,
2
,
OP_ADD
);
err
=
vp
->
Compute
(
g
,
val
,
2
,
OP_ADD
);
break
;
default:
val
[
0
]
=
Value
;
val
[
0
]
=
Nodes
[
n
].
Valp
;
val
[
1
]
=
MulVal
;
err
=
Value
->
Compute
(
g
,
val
,
2
,
Nodes
[
Ival
].
O
p
);
err
=
vp
->
Compute
(
g
,
val
,
2
,
o
p
);
}
// endswitch Op
if
(
err
)
Value
->
Reset
();
vp
->
Reset
();
}
// endif Zero
}
// endif Nx
}
while
(
Tjp
->
NextSame
>
nextsame
);
if
(
ars
>
++
Nx
)
{
if
(
Ival
!=
n
)
{
mode
=
2
;
goto
evenmore
;
}
else
goto
more
;
}
// endfor i
}
else
{
if
(
Nodes
[
Ival
].
Op
==
OP_SEP
)
{
if
(
op
==
OP_SEP
)
{
// Calculate average
PVAL
val
[
2
];
MulVal
->
SetValue
(
ars
);
val
[
0
]
=
Value
;
MulVal
->
SetValue
(
nv
);
val
[
0
]
=
vp
;
val
[
1
]
=
MulVal
;
if
(
Value
->
Compute
(
g
,
val
,
2
,
OP_DIV
))
Value
->
Reset
();
if
(
vp
->
Compute
(
g
,
val
,
2
,
OP_DIV
))
vp
->
Reset
();
}
// endif Op
Arp
=
NULL
;
Nx
=
0
;
}
// endif ars
Tjp
->
NextSame
=
nextsame
;
return
vp
;
}
// end of CalculateArray
}
// endif Op
/***********************************************************************/
/* GetRow: Get the object containing this column. */
/***********************************************************************/
PJSON
JSONCOL
::
GetRow
(
PGLOBAL
g
)
{
PJVAL
val
;
PJAR
arp
;
PJSON
nwr
,
row
=
Tjp
->
Row
;
}
// endif Arp
for
(
int
i
=
0
;
i
<
Nod
-
1
&&
row
;
i
++
)
{
if
(
Nodes
[
i
+
1
].
Op
==
OP_XX
)
break
;
else
switch
(
row
->
GetType
())
{
case
TYPE_JOB
:
if
(
!
Nodes
[
i
].
Key
)
// Expected Array was not there
continue
;
}
// end of ReadColumn
val
=
((
PJOB
)
row
)
->
GetValue
(
Nodes
[
i
].
Key
);
break
;
case
TYPE_JAR
:
if
(
!
Nodes
[
i
].
Key
)
{
if
(
Nodes
[
i
].
Op
!=
OP_NULL
)
{
arp
=
(
PJAR
)
row
;
if
(
Nodes
[
i
].
Rank
)
val
=
arp
->
GetValue
(
Nodes
[
i
].
Rank
-
1
);
else
val
=
arp
->
GetValue
(
Nodes
[
i
].
Nx
);
}
else
val
=
NULL
;
}
else
{
strcpy
(
g
->
Message
,
"Unexpected array"
);
val
=
NULL
;
// Not an expected array
}
// endif Nodes
break
;
case
TYPE_JVAL
:
val
=
(
PJVAL
)
row
;
break
;
default:
sprintf
(
g
->
Message
,
"Invalid row JSON type %d"
,
row
->
GetType
());
val
=
NULL
;
}
// endswitch Type
if
(
val
)
{
row
=
val
->
GetJson
();
}
else
{
// Construct missing objects
for
(
i
++
;
row
&&
i
<
Nod
;
i
++
)
{
if
(
Nodes
[
i
].
Op
==
OP_XX
)
break
;
else
if
(
!
Nodes
[
i
].
Key
)
// Construct intermediate array
nwr
=
new
(
g
)
JARRAY
;
else
nwr
=
new
(
g
)
JOBJECT
;
if
(
row
->
GetType
()
==
TYPE_JOB
)
{
((
PJOB
)
row
)
->
SetValue
(
g
,
new
(
g
)
JVALUE
(
nwr
),
Nodes
[
i
-
1
].
Key
);
}
else
if
(
row
->
GetType
()
==
TYPE_JAR
)
{
((
PJAR
)
row
)
->
AddValue
(
g
,
new
(
g
)
JVALUE
(
nwr
));
((
PJAR
)
row
)
->
InitArray
(
g
);
}
else
{
strcpy
(
g
->
Message
,
"Wrong type when writing new row"
);
nwr
=
NULL
;
}
// endif's
row
=
nwr
;
}
// endfor i
break
;
}
// endelse
}
// endfor i
return
row
;
}
// end of GetRow
/***********************************************************************/
/* WriteColumn: */
...
...
@@ -817,10 +913,11 @@ void JSONCOL::WriteColumn(PGLOBAL g)
if
(
Value
->
IsNull
()
&&
Tjp
->
Mode
==
MODE_INSERT
)
return
;
char
*
s
;
PJOB
objp
=
NULL
;
PJAR
arp
=
NULL
;
PJVAL
jvp
=
NULL
;
PJSON
row
=
GetRow
(
g
,
1
);
PJSON
jsp
,
row
=
GetRow
(
g
);
JTYP
type
=
row
->
GetType
();
switch
(
row
->
GetType
())
{
...
...
@@ -832,6 +929,28 @@ void JSONCOL::WriteColumn(PGLOBAL g)
if
(
row
)
switch
(
Buf_Type
)
{
case
TYPE_STRING
:
if
(
Nodes
[
Nod
-
1
].
Op
==
OP_XX
)
{
s
=
Value
->
GetCharValue
();
jsp
=
ParseJson
(
g
,
s
,
(
int
)
strlen
(
s
),
0
);
if
(
arp
)
{
if
(
Nod
>
1
&&
Nodes
[
Nod
-
2
].
Rank
)
arp
->
SetValue
(
g
,
new
(
g
)
JVALUE
(
jsp
),
Nodes
[
Nod
-
2
].
Rank
-
1
);
else
arp
->
AddValue
(
g
,
new
(
g
)
JVALUE
(
jsp
));
arp
->
InitArray
(
g
);
}
else
if
(
objp
)
{
if
(
Nod
>
1
&&
Nodes
[
Nod
-
2
].
Key
)
objp
->
SetValue
(
g
,
new
(
g
)
JVALUE
(
jsp
),
Nodes
[
Nod
-
2
].
Key
);
}
else
if
(
jvp
)
jvp
->
SetValue
(
jsp
);
break
;
}
// endif Op
// Passthru
case
TYPE_DATE
:
case
TYPE_INT
:
case
TYPE_DOUBLE
:
...
...
@@ -1175,11 +1294,6 @@ bool TDBJSON::OpenDB(PGLOBAL g)
/*******************************************************************/
/* Table already open replace it at its beginning. */
/*******************************************************************/
for
(
PJCOL
cp
=
(
PJCOL
)
Columns
;
cp
;
cp
=
(
PJCOL
)
cp
->
GetNext
())
{
cp
->
Nx
=
0
;
cp
->
Arp
=
NULL
;
}
// endfor cp
Fpos
=
-
1
;
Spos
=
0
;
NextSame
=
false
;
...
...
@@ -1217,7 +1331,8 @@ int TDBJSON::ReadDB(PGLOBAL g)
N
++
;
if
(
NextSame
)
{
SameRow
++
;
SameRow
=
NextSame
;
NextSame
=
false
;
rc
=
RC_OK
;
}
else
if
(
++
Fpos
<
(
signed
)
Doc
->
size
())
{
Row
=
Doc
->
GetValue
(
Fpos
);
...
...
@@ -1257,9 +1372,10 @@ int TDBJSON::WriteDB(PGLOBAL g)
return
RC_FX
;
}
else
{
// if (Jmode == MODE_VALUE)
if
(
Mode
==
MODE_INSERT
)
if
(
Mode
==
MODE_INSERT
)
{
Doc
->
AddValue
(
g
,
(
PJVAL
)
Row
);
else
if
(
Doc
->
SetValue
(
g
,
(
PJVAL
)
Row
,
Fpos
))
Row
=
new
(
g
)
JVALUE
;
}
else
if
(
Doc
->
SetValue
(
g
,
(
PJVAL
)
Row
,
Fpos
))
return
RC_FX
;
}
// endif Jmode
...
...
storage/connect/tabjson.h
View file @
56114a41
...
...
@@ -16,8 +16,6 @@ typedef class JSONDEF *PJDEF;
typedef
class
TDBJSON
*
PJTDB
;
typedef
class
JSONCOL
*
PJCOL
;
class
TDBJSN
;
/***********************************************************************/
/* The JSON tree node. Can be an Object or an Array. */
/***********************************************************************/
...
...
@@ -25,7 +23,9 @@ typedef struct _jnode {
PSZ
Key
;
// The key used for object
OPVAL
Op
;
// Operator used for this node
PVAL
CncVal
;
// To cont value used for OP_CNC
PVAL
Valp
;
// The internal array VALUE
int
Rank
;
// The rank in array
int
Nx
;
// Same row number
}
JNODE
,
*
PJNODE
;
/***********************************************************************/
...
...
@@ -77,7 +77,7 @@ class TDBJSN : public TDBDOS {
virtual
PTDB
CopyOne
(
PTABS
t
);
virtual
PCOL
MakeCol
(
PGLOBAL
g
,
PCOLDEF
cdp
,
PCOL
cprec
,
int
n
);
virtual
PCOL
InsertSpecialColumn
(
PGLOBAL
g
,
PCOL
colp
);
virtual
int
RowNumber
(
PGLOBAL
g
,
BOOL
b
=
FALSE
)
virtual
int
RowNumber
(
PGLOBAL
g
,
bool
b
=
FALSE
)
{
return
(
b
)
?
N
:
Fpos
+
1
;}
// Database routines
...
...
@@ -98,11 +98,11 @@ class TDBJSN : public TDBDOS {
int
N
;
// The current Rownum
int
Limit
;
// Limit of multiple values
int
Pretty
;
// Depends on file structure
bool
Strict
;
// Strict syntax checking
bool
NextSame
;
// Same next row
bool
Comma
;
// Row has final comma
int
NextSame
;
// Same next row
int
SameRow
;
// Same row nb
int
Xval
;
// Index of expandable array
bool
Strict
;
// Strict syntax checking
bool
Comma
;
// Row has final comma
};
// end of class TDBJSN
/* -------------------------- JSONCOL class -------------------------- */
...
...
@@ -130,8 +130,12 @@ class JSONCOL : public DOSCOL {
protected:
bool
CheckExpand
(
PGLOBAL
g
,
int
i
,
PSZ
nm
,
bool
b
);
bool
SetArrayOptions
(
PGLOBAL
g
,
char
*
p
,
int
i
,
PSZ
nm
);
PJSON
GetRow
(
PGLOBAL
g
,
int
mode
);
PVAL
GetColumnValue
(
PGLOBAL
g
,
PJSON
row
,
int
i
);
PVAL
ExpandArray
(
PGLOBAL
g
,
PJAR
arp
,
int
n
);
PVAL
CalculateArray
(
PGLOBAL
g
,
PJAR
arp
,
int
n
);
PVAL
MakeJson
(
PGLOBAL
g
,
PJSON
jsp
);
void
SetJsonValue
(
PGLOBAL
g
,
PVAL
vp
,
PJVAL
val
,
int
n
);
PJSON
GetRow
(
PGLOBAL
g
);
// Default constructor not to be used
JSONCOL
(
void
)
{}
...
...
@@ -139,12 +143,10 @@ class JSONCOL : public DOSCOL {
// Members
TDBJSN
*
Tjp
;
// To the JSN table block
PVAL
MulVal
;
// To value used by multiple column
PJAR
Arp
;
// The intermediate array
char
*
Jpath
;
// The json path
JNODE
*
Nodes
;
// The intermediate objects
JNODE
*
Nodes
;
// The intermediate objects
int
Nod
;
// The number of intermediate objects
int
Ival
;
// Index of multiple values
int
Nx
;
// The last read sub-row
int
Xnod
;
// Index of multiple values
bool
Xpd
;
// True for expandable column
bool
Parsed
;
// True when parsed
};
// end of class JSONCOL
...
...
storage/connect/tabmysql.cpp
View file @
56114a41
...
...
@@ -1141,20 +1141,17 @@ int TDBMYSQL::WriteDB(PGLOBAL g)
int
rc
;
uint
len
=
Query
->
GetLength
();
char
buf
[
64
];
bool
b
,
oom
=
false
;
bool
oom
=
false
;
// Make the Insert command value list
for
(
PCOL
colp
=
Columns
;
colp
;
colp
=
colp
->
GetNext
())
{
if
(
!
colp
->
GetValue
()
->
IsNull
())
{
if
(
(
b
=
colp
->
GetResultType
()
==
TYPE_STRING
||
colp
->
GetResultType
()
==
TYPE_DATE
)
)
oom
|=
Query
->
Append
(
'\''
);
if
(
colp
->
GetResultType
()
==
TYPE_STRING
||
colp
->
GetResultType
()
==
TYPE_DATE
)
oom
|=
Query
->
Append
_quoted
(
colp
->
GetValue
()
->
GetCharString
(
buf
)
);
else
oom
|=
Query
->
Append
(
colp
->
GetValue
()
->
GetCharString
(
buf
));
if
(
b
)
oom
|=
Query
->
Append
(
'\''
);
}
else
oom
|=
Query
->
Append
(
"NULL"
);
...
...
storage/connect/taboccur.cpp
View file @
56114a41
...
...
@@ -355,7 +355,7 @@ bool TDBOCCUR::MakeColumnList(PGLOBAL g)
for
(
colp
=
Columns
;
colp
;
colp
=
colp
->
GetNext
())
if
(
colp
->
GetAmType
()
==
TYPE_AM_PRX
)
if
(((
PPRXCOL
)
colp
)
->
Init
(
g
))
if
(((
PPRXCOL
)
colp
)
->
Init
(
g
,
NULL
))
return
true
;
Col
=
(
PCOL
*
)
PlugSubAlloc
(
g
,
NULL
,
Mult
*
sizeof
(
PCOL
));
...
...
storage/connect/tabodbc.cpp
View file @
56114a41
...
...
@@ -66,8 +66,8 @@
#include "plgdbsem.h"
#include "mycat.h"
#include "xtable.h"
#include "tabodbc.h"
#include "odbccat.h"
#include "tabodbc.h"
#include "tabmul.h"
#include "reldef.h"
#include "tabcol.h"
...
...
@@ -93,9 +93,10 @@ bool ExactInfo(void);
/***********************************************************************/
ODBCDEF
::
ODBCDEF
(
void
)
{
Connect
=
Tabname
=
Tabschema
=
Tabcat
=
Srcdef
=
Qchar
=
Qrystr
=
Sep
=
NULL
;
Connect
=
Tabname
=
Tabschema
=
Username
=
Password
=
NULL
;
Tabcat
=
Srcdef
=
Qchar
=
Qrystr
=
Sep
=
NULL
;
Catver
=
Options
=
Cto
=
Qto
=
Quoted
=
Maxerr
=
Maxres
=
0
;
Scrollable
=
Memory
=
Xsrc
=
false
;
Scrollable
=
Memory
=
Xsrc
=
UseCnc
=
false
;
}
// end of ODBCDEF constructor
/***********************************************************************/
...
...
@@ -117,6 +118,8 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Tabschema
=
GetStringCatInfo
(
g
,
"Schema"
,
Tabschema
);
Tabcat
=
GetStringCatInfo
(
g
,
"Qualifier"
,
NULL
);
Tabcat
=
GetStringCatInfo
(
g
,
"Catalog"
,
Tabcat
);
Username
=
GetStringCatInfo
(
g
,
"User"
,
NULL
);
Password
=
GetStringCatInfo
(
g
,
"Password"
,
NULL
);
if
((
Srcdef
=
GetStringCatInfo
(
g
,
"Srcdef"
,
NULL
)))
Read_Only
=
true
;
...
...
@@ -133,6 +136,7 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Cto
=
GetIntCatInfo
(
"ConnectTimeout"
,
DEFAULT_LOGIN_TIMEOUT
);
Qto
=
GetIntCatInfo
(
"QueryTimeout"
,
DEFAULT_QUERY_TIMEOUT
);
Scrollable
=
GetBoolCatInfo
(
"Scrollable"
,
false
);
UseCnc
=
GetBoolCatInfo
(
"UseDSN"
,
false
);
Memory
=
GetBoolCatInfo
(
"Memory"
,
false
);
Pseudo
=
2
;
// FILID is Ok but not ROWID
return
false
;
...
...
@@ -190,34 +194,40 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp)
Connect
=
tdp
->
Connect
;
TableName
=
tdp
->
Tabname
;
Schema
=
tdp
->
Tabschema
;
Ops
.
User
=
tdp
->
Username
;
Ops
.
Pwd
=
tdp
->
Password
;
Catalog
=
tdp
->
Tabcat
;
Srcdef
=
tdp
->
Srcdef
;
Qrystr
=
tdp
->
Qrystr
;
Sep
=
tdp
->
GetSep
();
Options
=
tdp
->
Options
;
Cto
=
tdp
->
Cto
;
Qto
=
tdp
->
Qto
;
Ops
.
Cto
=
tdp
->
Cto
;
Ops
.
Qto
=
tdp
->
Qto
;
Quoted
=
MY_MAX
(
0
,
tdp
->
GetQuoted
());
Rows
=
tdp
->
GetElemt
();
Catver
=
tdp
->
Catver
;
Memory
=
(
tdp
->
Memory
)
?
1
:
0
;
Scrollable
=
tdp
->
Scrollable
;
Ops
.
UseCnc
=
tdp
->
UseCnc
;
}
else
{
Connect
=
NULL
;
TableName
=
NULL
;
Schema
=
NULL
;
Ops
.
User
=
NULL
;
Ops
.
Pwd
=
NULL
;
Catalog
=
NULL
;
Srcdef
=
NULL
;
Qrystr
=
NULL
;
Sep
=
0
;
Options
=
0
;
Cto
=
DEFAULT_LOGIN_TIMEOUT
;
Qto
=
DEFAULT_QUERY_TIMEOUT
;
Ops
.
Cto
=
DEFAULT_LOGIN_TIMEOUT
;
Ops
.
Qto
=
DEFAULT_QUERY_TIMEOUT
;
Quoted
=
0
;
Rows
=
0
;
Catver
=
0
;
Memory
=
0
;
Scrollable
=
false
;
Ops
.
UseCnc
=
false
;
}
// endif tdp
Quote
=
NULL
;
...
...
@@ -242,6 +252,7 @@ TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp)
Connect
=
tdbp
->
Connect
;
TableName
=
tdbp
->
TableName
;
Schema
=
tdbp
->
Schema
;
Ops
=
tdbp
->
Ops
;
Catalog
=
tdbp
->
Catalog
;
Srcdef
=
tdbp
->
Srcdef
;
Qrystr
=
tdbp
->
Qrystr
;
...
...
@@ -254,8 +265,6 @@ TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp)
MulConn
=
tdbp
->
MulConn
;
DBQ
=
tdbp
->
DBQ
;
Options
=
tdbp
->
Options
;
Cto
=
tdbp
->
Cto
;
Qto
=
tdbp
->
Qto
;
Quoted
=
tdbp
->
Quoted
;
Rows
=
tdbp
->
Rows
;
Fpos
=
tdbp
->
Fpos
;
...
...
@@ -370,7 +379,7 @@ int TDBODBC::Decode(char *txt, char *buf, size_t n)
/***********************************************************************/
char
*
TDBODBC
::
MakeSQL
(
PGLOBAL
g
,
bool
cnt
)
{
char
*
colist
,
*
tabname
,
*
sql
,
buf
[
64
];
char
*
colist
,
*
tabname
,
*
sql
,
buf
[
NAM_LEN
*
3
];
LPCSTR
schmp
=
NULL
,
catp
=
NULL
;
int
len
,
ncol
=
0
;
bool
first
=
true
;
...
...
@@ -475,6 +484,9 @@ char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
if
(
To_CondFil
)
strcat
(
strcat
(
sql
,
" WHERE "
),
To_CondFil
->
Body
);
if
(
trace
)
htrc
(
"sql: '%s'
\n
"
,
sql
);
return
sql
;
}
// end of MakeSQL
...
...
@@ -483,7 +495,7 @@ char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
/***********************************************************************/
char
*
TDBODBC
::
MakeInsert
(
PGLOBAL
g
)
{
char
*
stmt
,
*
colist
,
*
valist
;
char
*
stmt
,
*
colist
,
*
valist
,
buf
[
NAM_LEN
*
3
]
;
// char *tk = "`";
int
len
=
0
;
bool
b
=
FALSE
;
...
...
@@ -510,10 +522,13 @@ char *TDBODBC::MakeInsert(PGLOBAL g)
}
else
b
=
true
;
// Column name can be in UTF-8 encoding
Decode
(
colp
->
GetName
(),
buf
,
sizeof
(
buf
));
if
(
Quote
)
strcat
(
strcat
(
strcat
(
colist
,
Quote
),
colp
->
GetName
()
),
Quote
);
strcat
(
strcat
(
strcat
(
colist
,
Quote
),
buf
),
Quote
);
else
strcat
(
colist
,
colp
->
GetName
()
);
strcat
(
colist
,
buf
);
strcat
(
valist
,
"?"
);
// Parameter marker
}
// endfor colp
...
...
@@ -558,8 +573,7 @@ bool TDBODBC::BindParameters(PGLOBAL g)
/***********************************************************************/
char
*
TDBODBC
::
MakeCommand
(
PGLOBAL
g
)
{
char
*
p
,
name
[
68
],
*
qc
=
Ocp
->
GetQuoteChar
();
char
*
stmt
=
(
char
*
)
PlugSubAlloc
(
g
,
NULL
,
strlen
(
Qrystr
)
+
64
);
char
*
p
,
*
stmt
,
name
[
68
],
*
body
=
NULL
,
*
qc
=
Ocp
->
GetQuoteChar
();
char
*
qrystr
=
(
char
*
)
PlugSubAlloc
(
g
,
NULL
,
strlen
(
Qrystr
)
+
1
);
bool
qtd
=
Quoted
>
0
;
int
i
=
0
,
k
=
0
;
...
...
@@ -570,6 +584,15 @@ char *TDBODBC::MakeCommand(PGLOBAL g)
qrystr
[
i
]
=
(
Qrystr
[
i
]
==
'`'
)
?
*
qc
:
tolower
(
Qrystr
[
i
]);
}
while
(
Qrystr
[
i
++
]);
if
(
To_CondFil
&&
(
p
=
strstr
(
qrystr
,
" where "
)))
{
p
[
7
]
=
0
;
// Remove where clause
Qrystr
[(
p
-
qrystr
)
+
7
]
=
0
;
body
=
To_CondFil
->
Body
;
stmt
=
(
char
*
)
PlugSubAlloc
(
g
,
NULL
,
strlen
(
qrystr
)
+
strlen
(
body
)
+
64
);
}
else
stmt
=
(
char
*
)
PlugSubAlloc
(
g
,
NULL
,
strlen
(
Qrystr
)
+
64
);
// Check whether the table name is equal to a keyword
// If so, it must be quoted in the original query
strlwr
(
strcat
(
strcat
(
strcpy
(
name
,
" "
),
Name
),
" "
));
...
...
@@ -597,6 +620,9 @@ char *TDBODBC::MakeCommand(PGLOBAL g)
stmt
[
i
++
]
=
(
Qrystr
[
k
]
==
'`'
)
?
*
qc
:
Qrystr
[
k
];
}
while
(
Qrystr
[
k
++
]);
if
(
body
)
strcat
(
stmt
,
body
);
}
else
{
sprintf
(
g
->
Message
,
"Cannot use this %s command"
,
(
Mode
==
MODE_UPDATE
)
?
"UPDATE"
:
"DELETE"
);
...
...
@@ -698,10 +724,7 @@ int TDBODBC::Cardinality(PGLOBAL g)
char
qry
[
96
],
tbn
[
64
];
ODBConn
*
ocp
=
new
(
g
)
ODBConn
(
g
,
this
);
ocp
->
SetLoginTimeout
((
DWORD
)
Cto
);
ocp
->
SetQueryTimeout
((
DWORD
)
Qto
);
if
(
ocp
->
Open
(
Connect
,
Options
)
<
1
)
if
(
ocp
->
Open
(
Connect
,
&
Ops
,
Options
)
<
1
)
return
-
1
;
// Table name can be encoded in UTF-8
...
...
@@ -762,7 +785,7 @@ int TDBODBC::GetProgMax(PGLOBAL g)
/***********************************************************************/
bool
TDBODBC
::
OpenDB
(
PGLOBAL
g
)
{
bool
rc
=
fals
e
;
bool
rc
=
tru
e
;
if
(
g
->
Trace
)
htrc
(
"ODBC OpenDB: tdbp=%p tdb=R%d use=%dmode=%d
\n
"
,
...
...
@@ -802,14 +825,12 @@ bool TDBODBC::OpenDB(PGLOBAL g)
/* and if so to allocate just a new result set. But this only for */
/* drivers allowing concurency in getting results ??? */
/*********************************************************************/
if
(
!
Ocp
)
{
if
(
!
Ocp
)
Ocp
=
new
(
g
)
ODBConn
(
g
,
this
);
Ocp
->
SetLoginTimeout
((
DWORD
)
Cto
);
Ocp
->
SetQueryTimeout
((
DWORD
)
Qto
);
}
else
if
(
Ocp
->
IsOpen
())
else
if
(
Ocp
->
IsOpen
())
Ocp
->
Close
();
if
(
Ocp
->
Open
(
Connect
,
Options
)
<
1
)
if
(
Ocp
->
Open
(
Connect
,
&
Ops
,
Options
)
<
1
)
return
true
;
else
if
(
Quoted
)
Quote
=
Ocp
->
GetQuoteChar
();
...
...
@@ -839,12 +860,12 @@ bool TDBODBC::OpenDB(PGLOBAL g)
}
// endif Query
}
else
if
(
Mode
==
MODE_UPDATE
||
Mode
==
MODE_DELETE
)
Query
=
MakeCommand
(
g
);
else
}
else
if
(
Mode
==
MODE_UPDATE
||
Mode
==
MODE_DELETE
)
{
rc
=
false
;
// wait for CheckCond before calling
MakeCommand(g);
}
else
sprintf
(
g
->
Message
,
"Invalid mode %d"
,
Mode
);
if
(
!
Query
||
rc
)
{
if
(
rc
)
{
Ocp
->
Close
();
return
true
;
}
// endif rc
...
...
@@ -876,6 +897,9 @@ int TDBODBC::ReadDB(PGLOBAL g)
GetTdb_No
(),
Mode
,
To_Key_Col
,
To_Link
,
To_Kindex
);
if
(
Mode
==
MODE_UPDATE
||
Mode
==
MODE_DELETE
)
{
if
(
!
Query
&&
!
(
Query
=
MakeCommand
(
g
)))
return
RC_FX
;
// Send the UPDATE/DELETE command to the remote table
if
(
!
Ocp
->
ExecSQLcommand
(
Query
))
{
sprintf
(
g
->
Message
,
"%s: %d affected rows"
,
TableName
,
AftRows
);
...
...
@@ -945,6 +969,9 @@ int TDBODBC::WriteDB(PGLOBAL g)
int
TDBODBC
::
DeleteDB
(
PGLOBAL
g
,
int
irc
)
{
if
(
irc
==
RC_FX
)
{
if
(
!
Query
&&
!
(
Query
=
MakeCommand
(
g
)))
return
RC_FX
;
// Send the DELETE (all) command to the remote table
if
(
!
Ocp
->
ExecSQLcommand
(
Query
))
{
sprintf
(
g
->
Message
,
"%s: %d affected rows"
,
TableName
,
AftRows
);
...
...
@@ -1415,12 +1442,10 @@ bool TDBXDBC::OpenDB(PGLOBAL g)
/*********************************************************************/
if
(
!
Ocp
)
{
Ocp
=
new
(
g
)
ODBConn
(
g
,
this
);
Ocp
->
SetLoginTimeout
((
DWORD
)
Cto
);
Ocp
->
SetQueryTimeout
((
DWORD
)
Qto
);
}
else
if
(
Ocp
->
IsOpen
())
Ocp
->
Close
();
if
(
Ocp
->
Open
(
Connect
,
Options
)
<
1
)
if
(
Ocp
->
Open
(
Connect
,
&
Ops
,
Options
)
<
1
)
return
true
;
Use
=
USE_OPEN
;
// Do it now in case we are recursively called
...
...
@@ -1554,8 +1579,11 @@ TDBOTB::TDBOTB(PODEF tdp) : TDBDRV(tdp)
Dsn
=
tdp
->
GetConnect
();
Schema
=
tdp
->
GetTabschema
();
Tab
=
tdp
->
GetTabname
();
Cto
=
tdp
->
Cto
;
Qto
=
tdp
->
Qto
;
Ops
.
User
=
tdp
->
Username
;
Ops
.
Pwd
=
tdp
->
Password
;
Ops
.
Cto
=
tdp
->
Cto
;
Ops
.
Qto
=
tdp
->
Qto
;
Ops
.
UseCnc
=
tdp
->
UseCnc
;
}
// end of TDBOTB constructor
/***********************************************************************/
...
...
@@ -1563,7 +1591,7 @@ TDBOTB::TDBOTB(PODEF tdp) : TDBDRV(tdp)
/***********************************************************************/
PQRYRES
TDBOTB
::
GetResult
(
PGLOBAL
g
)
{
return
ODBCTables
(
g
,
Dsn
,
Schema
,
Tab
,
Maxres
,
Cto
,
Qto
,
false
);
return
ODBCTables
(
g
,
Dsn
,
Schema
,
Tab
,
Maxres
,
false
,
&
Ops
);
}
// end of GetResult
/* ---------------------------TDBOCL class --------------------------- */
...
...
@@ -1573,7 +1601,7 @@ PQRYRES TDBOTB::GetResult(PGLOBAL g)
/***********************************************************************/
PQRYRES
TDBOCL
::
GetResult
(
PGLOBAL
g
)
{
return
ODBCColumns
(
g
,
Dsn
,
Schema
,
Tab
,
NULL
,
Maxres
,
Cto
,
Qto
,
false
);
return
ODBCColumns
(
g
,
Dsn
,
Schema
,
Tab
,
NULL
,
Maxres
,
false
,
&
Ops
);
}
// end of GetResult
/* ------------------------ End of Tabodbc --------------------------- */
storage/connect/tabodbc.h
View file @
56114a41
...
...
@@ -50,6 +50,8 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
PSZ
Connect
;
/* ODBC connection string */
PSZ
Tabname
;
/* External table name */
PSZ
Tabschema
;
/* External table schema */
PSZ
Username
;
/* User connect name */
PSZ
Password
;
/* Password connect info */
PSZ
Tabcat
;
/* External table catalog */
PSZ
Srcdef
;
/* The source table SQL definition */
PSZ
Qchar
;
/* Identifier quoting character */
...
...
@@ -65,6 +67,7 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
bool
Scrollable
;
/* Use scrollable cursor */
bool
Memory
;
/* Put result set in memory */
bool
Xsrc
;
/* Execution type */
bool
UseCnc
;
/* Use SQLConnect (!SQLDriverConnect) */
};
// end of ODBCDEF
#if !defined(NODBC)
...
...
@@ -124,9 +127,12 @@ class TDBODBC : public TDBASE {
// Members
ODBConn
*
Ocp
;
// Points to an ODBC connection class
ODBCCOL
*
Cnp
;
// Points to count(*) column
ODBCPARM
Ops
;
// Additional parameters
char
*
Connect
;
// Points to connection string
char
*
TableName
;
// Points to ODBC table name
char
*
Schema
;
// Points to ODBC table Schema
char
*
User
;
// User connect info
char
*
Pwd
;
// Password connect info
char
*
Catalog
;
// Points to ODBC table Catalog
char
*
Srcdef
;
// The source table SQL definition
char
*
Query
;
// Points to SQL statement
...
...
@@ -151,6 +157,7 @@ class TDBODBC : public TDBASE {
int
Nparm
;
// The number of statement parameters
int
Memory
;
// 0: No 1: Alloc 2: Put 3: Get
bool
Scrollable
;
// Use scrollable cursor
bool
UseCnc
;
// Use SQLConnect (!SQLDriverConnect)
PQRYRES
Qrp
;
// Points to storage result
};
// end of class TDBODBC
...
...
@@ -316,8 +323,7 @@ class TDBOTB : public TDBDRV {
char
*
Dsn
;
// Points to connection string
char
*
Schema
;
// Points to schema name or NULL
char
*
Tab
;
// Points to ODBC table name or pattern
int
Cto
;
// Connect timeout
int
Qto
;
// Query timeout
ODBCPARM
Ops
;
// Additional parameters
};
// end of class TDBOTB
/***********************************************************************/
...
...
storage/connect/tabpivot.cpp
View file @
56114a41
...
...
@@ -558,7 +558,7 @@ bool TDBPIVOT::MakePivotColumns(PGLOBAL g)
// Check and initialize the subtable columns
for
(
PCOL
cp
=
Columns
;
cp
;
cp
=
cp
->
GetNext
())
if
(
cp
->
GetAmType
()
==
TYPE_AM_SRC
)
{
if
(((
PSRCCOL
)
cp
)
->
Init
(
g
))
if
(((
PSRCCOL
)
cp
)
->
Init
(
g
,
NULL
))
return
TRUE
;
}
else
if
(
cp
->
GetAmType
()
==
TYPE_AM_FNC
)
...
...
@@ -874,9 +874,9 @@ SRCCOL::SRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int n)
/***********************************************************************/
/* Initialize the column as pointing to the source column. */
/***********************************************************************/
bool
SRCCOL
::
Init
(
PGLOBAL
g
)
bool
SRCCOL
::
Init
(
PGLOBAL
g
,
PTDBASE
tp
)
{
if
(
PRXCOL
::
Init
(
g
))
if
(
PRXCOL
::
Init
(
g
,
tp
))
return
true
;
AddStatus
(
BUF_READ
);
// All is done here
...
...
storage/connect/tabpivot.h
View file @
56114a41
...
...
@@ -180,9 +180,10 @@ class SRCCOL : public PRXCOL {
virtual
int
GetAmType
(
void
)
{
return
TYPE_AM_SRC
;}
// Methods
using
PRXCOL
::
Init
;
virtual
void
Reset
(
void
)
{}
void
SetColumn
(
void
);
bool
Init
(
PGLOBAL
g
);
virtual
bool
Init
(
PGLOBAL
g
,
PTDBASE
tp
);
bool
CompareLast
(
void
);
protected:
...
...
storage/connect/tabtbl.cpp
View file @
56114a41
...
...
@@ -266,7 +266,7 @@ bool TDBTBL::InitTableList(PGLOBAL g)
// Real initialization will be done later.
for
(
colp
=
Columns
;
colp
;
colp
=
colp
->
GetNext
())
if
(
!
colp
->
IsSpecial
())
if
(((
PPRXCOL
)
colp
)
->
Init
(
g
)
&&
!
Accept
)
if
(((
PPRXCOL
)
colp
)
->
Init
(
g
,
NULL
)
&&
!
Accept
)
return
TRUE
;
if
(
Tablist
)
...
...
@@ -352,7 +352,9 @@ bool TDBTBL::TestFil(PGLOBAL g, PCFIL filp, PTABLE tabp)
/***********************************************************************/
int
TDBTBL
::
Cardinality
(
PGLOBAL
g
)
{
if
(
Cardinal
<
0
)
{
if
(
!
g
)
return
0
;
// Cannot make the table list
else
if
(
Cardinal
<
0
)
{
int
tsz
;
if
(
!
Tablist
&&
InitTableList
(
g
))
...
...
@@ -468,7 +470,7 @@ bool TDBTBL::OpenDB(PGLOBAL g)
for
(
PCOL
cp
=
Columns
;
cp
;
cp
=
cp
->
GetNext
())
if
(
cp
->
GetAmType
()
==
TYPE_AM_TABID
)
cp
->
COLBLK
::
Reset
();
else
if
(((
PPRXCOL
)
cp
)
->
Init
(
g
)
&&
!
Accept
)
else
if
(((
PPRXCOL
)
cp
)
->
Init
(
g
,
NULL
)
&&
!
Accept
)
return
TRUE
;
if
(
trace
)
...
...
@@ -523,7 +525,7 @@ int TDBTBL::ReadDB(PGLOBAL g)
if
(
cp
->
GetAmType
()
==
TYPE_AM_TABID
||
cp
->
GetAmType
()
==
TYPE_AM_SRVID
)
cp
->
COLBLK
::
Reset
();
else
if
(((
PPRXCOL
)
cp
)
->
Init
(
g
)
&&
!
Accept
)
else
if
(((
PPRXCOL
)
cp
)
->
Init
(
g
,
NULL
)
&&
!
Accept
)
return
RC_FX
;
if
(
trace
)
...
...
@@ -716,7 +718,7 @@ bool TDBTBM::OpenDB(PGLOBAL g)
for
(
PCOL
cp
=
Columns
;
cp
;
cp
=
cp
->
GetNext
())
if
(
cp
->
GetAmType
()
==
TYPE_AM_TABID
)
cp
->
COLBLK
::
Reset
();
else
if
(((
PPRXCOL
)
cp
)
->
Init
(
g
)
&&
!
Accept
)
else
if
(((
PPRXCOL
)
cp
)
->
Init
(
g
,
NULL
)
&&
!
Accept
)
return
TRUE
;
if
(
trace
)
...
...
@@ -807,7 +809,7 @@ int TDBTBM::ReadNextRemote(PGLOBAL g)
for
(
PCOL
cp
=
Columns
;
cp
;
cp
=
cp
->
GetNext
())
if
(
cp
->
GetAmType
()
==
TYPE_AM_TABID
)
cp
->
COLBLK
::
Reset
();
else
if
(((
PPRXCOL
)
cp
)
->
Init
(
g
)
&&
!
Accept
)
else
if
(((
PPRXCOL
)
cp
)
->
Init
(
g
,
NULL
)
&&
!
Accept
)
return
RC_FX
;
if
(
trace
)
...
...
storage/connect/tabutil.cpp
View file @
56114a41
...
...
@@ -54,7 +54,8 @@
#include "tabutil.h"
#include "ha_connect.h"
extern
"C"
int
zconv
;
//extern "C" int zconv;
int
GetConvSize
(
void
);
/************************************************************************/
/* Used by MYSQL tables to get MySQL parameters from the calling proxy */
...
...
@@ -132,6 +133,7 @@ PQRYRES TabColumns(PGLOBAL g, THD *thd, const char *db,
char
*
fld
,
*
colname
,
*
chset
,
*
fmt
,
v
;
int
i
,
n
,
ncol
=
sizeof
(
buftyp
)
/
sizeof
(
int
);
int
prec
,
len
,
type
,
scale
;
int
zconv
=
GetConvSize
();
bool
mysql
;
TABLE_SHARE
*
s
=
NULL
;
Field
*
*
field
;
...
...
@@ -668,6 +670,22 @@ PRXCOL::PRXCOL(PRXCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp)
Colnum
=
col1
->
Colnum
;
}
// end of PRXCOL copy constructor
/***********************************************************************/
/* Convert an UTF-8 name to latin characters. */
/***********************************************************************/
char
*
PRXCOL
::
Decode
(
PGLOBAL
g
,
const
char
*
cnm
)
{
char
*
buf
=
(
char
*
)
PlugSubAlloc
(
g
,
NULL
,
strlen
(
cnm
)
+
1
);
uint
dummy_errors
;
uint32
len
=
copy_and_convert
(
buf
,
strlen
(
cnm
)
+
1
,
&
my_charset_latin1
,
cnm
,
strlen
(
cnm
),
&
my_charset_utf8_general_ci
,
&
dummy_errors
);
buf
[
len
]
=
'\0'
;
return
buf
;
}
// end of Decode
/***********************************************************************/
/* PRXCOL initialization routine. */
/* Look for the matching column in the object table. */
...
...
@@ -683,6 +701,9 @@ bool PRXCOL::Init(PGLOBAL g, PTDBASE tp)
if
(
Colp
)
{
MODE
mode
=
To_Tdb
->
GetMode
();
// Needed for MYSQL subtables
((
XCOLBLK
*
)
Colp
)
->
Name
=
Decode
(
g
,
Colp
->
GetName
());
// May not have been done elsewhere
Colp
->
InitValue
(
g
);
To_Val
=
Colp
->
GetValue
();
...
...
storage/connect/tabutil.h
View file @
56114a41
...
...
@@ -108,15 +108,18 @@ class DllExport PRXCOL : public COLBLK {
virtual
int
GetAmType
(
void
)
{
return
TYPE_AM_PRX
;}
// Methods
using
COLBLK
::
Init
;
virtual
void
Reset
(
void
);
virtual
bool
IsSpecial
(
void
)
{
return
Pseudo
;}
virtual
bool
SetBuffer
(
PGLOBAL
g
,
PVAL
value
,
bool
ok
,
bool
check
)
{
return
false
;}
virtual
void
ReadColumn
(
PGLOBAL
g
);
virtual
void
WriteColumn
(
PGLOBAL
g
);
virtual
bool
Init
(
PGLOBAL
g
,
PTDBASE
tp
=
NULL
);
virtual
bool
Init
(
PGLOBAL
g
,
PTDBASE
tp
);
protected:
char
*
Decode
(
PGLOBAL
g
,
const
char
*
cnm
);
// Default constructor not to be used
PRXCOL
(
void
)
{}
...
...
@@ -144,4 +147,8 @@ class TDBTBC : public TDBCAT {
PSZ
Tab
;
// Table name
};
// end of class TDBMCL
class
XCOLBLK
:
public
COLBLK
{
friend
class
PRXCOL
;
};
// end of class XCOLBLK
#endif // TABUTIL
storage/connect/tabxcl.cpp
View file @
56114a41
...
...
@@ -183,7 +183,7 @@ bool TDBXCL::OpenDB(PGLOBAL g)
/*********************************************************************/
for
(
PCOL
cp
=
Columns
;
cp
;
cp
=
cp
->
GetNext
())
if
(
!
cp
->
IsSpecial
())
if
(((
PPRXCOL
)
cp
)
->
Init
(
g
))
if
(((
PPRXCOL
)
cp
)
->
Init
(
g
,
NULL
))
return
TRUE
;
/*********************************************************************/
...
...
storage/connect/tabxcl.h
View file @
56114a41
...
...
@@ -88,6 +88,7 @@ class XCLCOL : public PRXCOL {
XCLCOL
(
PGLOBAL
g
,
PCOLDEF
cdp
,
PTDB
tdbp
,
PCOL
cprec
,
int
i
);
// Methods
using
PRXCOL
::
Init
;
virtual
void
Reset
(
void
)
{}
// Evaluated only by TDBXCL
virtual
void
ReadColumn
(
PGLOBAL
g
);
virtual
bool
Init
(
PGLOBAL
g
,
PTDBASE
tp
=
NULL
);
...
...
storage/connect/valblk.h
View file @
56114a41
...
...
@@ -163,6 +163,7 @@ class TYPBLK : public VALBLK {
virtual
void
Reset
(
int
n
)
{
Typp
[
n
]
=
0
;}
// Methods
using
VALBLK
::
SetValue
;
virtual
void
SetValue
(
PSZ
sp
,
int
n
);
virtual
void
SetValue
(
char
*
sp
,
uint
len
,
int
n
);
virtual
void
SetValue
(
short
sval
,
int
n
)
...
...
@@ -233,6 +234,7 @@ class CHRBLK : public VALBLK {
virtual
bool
IsCi
(
void
)
{
return
Ci
;}
// Methods
using
VALBLK
::
SetValue
;
virtual
void
SetValue
(
PSZ
sp
,
int
n
);
virtual
void
SetValue
(
char
*
sp
,
uint
len
,
int
n
);
virtual
void
SetValue
(
PVAL
valp
,
int
n
);
...
...
@@ -286,6 +288,7 @@ class STRBLK : public VALBLK {
virtual
void
Reset
(
int
n
)
{
Strp
[
n
]
=
NULL
;}
// Methods
using
VALBLK
::
SetValue
;
virtual
void
SetValue
(
PSZ
sp
,
int
n
);
virtual
void
SetValue
(
char
*
sp
,
uint
len
,
int
n
);
virtual
void
SetValue
(
PVAL
valp
,
int
n
);
...
...
@@ -322,6 +325,7 @@ class DATBLK : public TYPBLK<int> {
virtual
char
*
GetCharString
(
char
*
p
,
int
n
);
// Methods
using
TYPBLK
<
int
>::
SetValue
;
virtual
void
SetValue
(
PSZ
sp
,
int
n
);
protected:
...
...
@@ -345,6 +349,8 @@ class PTRBLK : public STRBLK {
// Implementation
// Methods
using
STRBLK
::
SetValue
;
using
STRBLK
::
CompVal
;
virtual
void
SetValue
(
PSZ
p
,
int
n
)
{
Strp
[
n
]
=
p
;}
virtual
int
CompVal
(
int
i1
,
int
i2
);
...
...
storage/connect/value.cpp
View file @
56114a41
...
...
@@ -436,6 +436,9 @@ PVAL AllocateValue(PGLOBAL g, PVAL valp, int newtype, int uns)
bool
un
=
(
uns
<
0
)
?
false
:
(
uns
>
0
)
?
true
:
valp
->
IsUnsigned
();
PVAL
vp
;
if
(
!
valp
)
return
NULL
;
if
(
newtype
==
TYPE_VOID
)
// Means allocate a value of the same type
newtype
=
valp
->
GetType
();
...
...
@@ -443,8 +446,8 @@ PVAL AllocateValue(PGLOBAL g, PVAL valp, int newtype, int uns)
case
TYPE_STRING
:
p
=
(
PSZ
)
PlugSubAlloc
(
g
,
NULL
,
1
+
valp
->
GetValLen
());
if
((
sp
=
valp
->
GetCharString
(
p
))
!=
p
)
strcpy
(
p
,
sp
);
if
((
sp
=
valp
->
GetCharString
(
p
))
!=
p
&&
sp
)
strcpy
(
p
,
sp
);
vp
=
new
(
g
)
TYPVAL
<
PSZ
>
(
g
,
p
,
valp
->
GetValLen
(),
valp
->
GetValPrec
());
break
;
...
...
@@ -1216,12 +1219,12 @@ TYPVAL<PSZ>::TYPVAL(PSZ s) : VALUE(TYPE_STRING)
TYPVAL
<
PSZ
>::
TYPVAL
(
PGLOBAL
g
,
PSZ
s
,
int
n
,
int
c
)
:
VALUE
(
TYPE_STRING
)
{
Len
=
(
g
)
?
n
:
strlen
(
s
)
;
Len
=
(
g
)
?
n
:
(
s
)
?
strlen
(
s
)
:
0
;
if
(
!
s
)
{
if
(
g
)
{
if
((
Strp
=
(
char
*
)
PlgDBSubAlloc
(
g
,
NULL
,
Len
+
1
)))
Strp
[
Len
]
=
'\0'
;
memset
(
Strp
,
0
,
Len
+
1
)
;
else
Len
=
0
;
...
...
storage/connect/xindex.h
View file @
56114a41
...
...
@@ -391,6 +391,7 @@ class DllExport XHUGE : public XLOAD {
XHUGE
(
void
)
:
XLOAD
()
{}
// Methods
using
XLOAD
::
Close
;
virtual
bool
Open
(
PGLOBAL
g
,
char
*
filename
,
int
id
,
MODE
mode
);
virtual
bool
Seek
(
PGLOBAL
g
,
int
low
,
int
high
,
int
origin
);
virtual
bool
Read
(
PGLOBAL
g
,
void
*
buf
,
int
n
,
int
size
);
...
...
storage/connect/xobject.cpp
View file @
56114a41
...
...
@@ -346,6 +346,31 @@ bool STRING::Append(char c)
return
false
;
}
// end of Append
/***********************************************************************/
/* Append a quoted PSZ to a STRING. */
/***********************************************************************/
bool
STRING
::
Append_quoted
(
PSZ
s
)
{
bool
b
=
Append
(
'\''
);
if
(
s
)
for
(
char
*
p
=
s
;
!
b
&&
*
p
;
p
++
)
switch
(
*
p
)
{
case
'\''
:
case
'\\'
:
case
'\t'
:
case
'\n'
:
case
'\r'
:
case
'\b'
:
case
'\f'
:
b
|=
Append
(
'\\'
);
// passthru
default:
b
|=
Append
(
*
p
);
break
;
}
// endswitch *p
return
(
b
|=
Append
(
'\''
));
}
// end of Append_quoted
/***********************************************************************/
/* Resize to given length but only when last suballocated. */
/* New size should be greater than string length. */
...
...
storage/connect/xobject.h
View file @
56114a41
...
...
@@ -138,6 +138,7 @@ class DllExport STRING : public BLOCK {
bool
Append
(
STRING
&
str
);
bool
Append
(
char
c
);
bool
Resize
(
uint
n
);
bool
Append_quoted
(
PSZ
s
);
inline
void
Trim
(
void
)
{(
void
)
Resize
(
Length
+
1
);}
inline
void
Chop
(
void
)
{
if
(
Length
)
Strp
[
--
Length
]
=
0
;}
inline
void
RepLast
(
char
c
)
{
if
(
Length
)
Strp
[
Length
-
1
]
=
c
;}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment