mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
- Add (limited) support for UPDATE and DELETE to ODBC tables
(also provide the possibility to issue NOTE warnings) modified: storage/connect/connect.cc storage/connect/ha_connect.cc storage/connect/ha_connect.h storage/connect/odbconn.cpp storage/connect/odbconn.h storage/connect/plgdbsem.h storage/connect/tabodbc.cpp storage/connect/tabodbc.h - Return proper error number when modifying read only tables modified: storage/connect/connect.cc storage/connect/ha_connect.cc storage/connect/ha_connect.h storage/connect/mysql-test/connect/r/bin.result storage/connect/mysql-test/connect/r/csv.result storage/connect/mysql-test/connect/r/dbf.result storage/connect/mysql-test/connect/r/fix.result storage/connect/mysql-test/connect/r/ini.result storage/connect/mysql-test/connect/r/vec.result storage/connect/mysql-test/connect/t/bin.test storage/connect/mysql-test/connect/t/csv.test storage/connect/mysql-test/connect/t/dbf.test storage/connect/mysql-test/connect/t/fix.test storage/connect/mysql-test/connect/t/ini.test storage/connect/mysql-test/connect/t/vec.test storage/connect/table.cpp storage/connect/taboccur.cpp storage/connect/tabpivot.cpp storage/connect/tabutil.cpp storage/connect/tabwmi.cpp storage/connect/tabxcl.cpp
This commit is contained in:
parent
e5c589a8da
commit
eca84a9b18
26 changed files with 1314 additions and 1251 deletions
|
@ -251,7 +251,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
|
|||
return true;
|
||||
} // endif tdbp
|
||||
|
||||
tdbp->SetMode(mode);
|
||||
//tdbp->SetMode(mode); done in ha_connect::GetTDB
|
||||
|
||||
if (!c1) {
|
||||
if (mode == MODE_INSERT)
|
||||
|
@ -498,8 +498,8 @@ RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all)
|
|||
|
||||
if (!tdbp || tdbp->GetMode() != MODE_DELETE)
|
||||
return RC_FX;
|
||||
// else
|
||||
// ((PTDBDOX)tdbp)->SetModified(true);
|
||||
else if (tdbp->IsReadOnly())
|
||||
return RC_NF;
|
||||
|
||||
if (((PTDBASE)tdbp)->GetDef()->Indexable() && all)
|
||||
((PTDBDOS)tdbp)->Cardinal= 0;
|
||||
|
@ -518,17 +518,13 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp)
|
|||
int rc= RC_OK;
|
||||
TDBDOX *tbxp= NULL;
|
||||
|
||||
if (!tdbp)
|
||||
return rc; // Already done
|
||||
if (!tdbp || tdbp->GetUse() != USE_OPEN)
|
||||
return rc; // Nothing to do
|
||||
|
||||
if (xtrace)
|
||||
printf("CntCloseTable: tdbp=%p mode=%d\n", tdbp, tdbp->GetMode());
|
||||
|
||||
/*********************************************************************/
|
||||
/* This will close the table file(s) and also finalize write */
|
||||
/* operations such as Insert, Update, or Delete. */
|
||||
/*********************************************************************/
|
||||
if (tdbp->GetMode() == MODE_DELETE)
|
||||
if (tdbp->GetMode() == MODE_DELETE && tdbp->GetUse() == USE_OPEN)
|
||||
rc= tdbp->DeleteDB(g, RC_EF); // Specific A.M. delete routine
|
||||
|
||||
// Prepare error return
|
||||
|
@ -543,6 +539,8 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp)
|
|||
goto err;
|
||||
} // endif
|
||||
|
||||
// This will close the table file(s) and also finalize write
|
||||
// operations such as Insert, Update, or Delete.
|
||||
tdbp->CloseDB(g);
|
||||
|
||||
g->jump_level--;
|
||||
|
|
|
@ -258,17 +258,21 @@ ha_create_table_option connect_field_option_list[]=
|
|||
/***********************************************************************/
|
||||
/* Push G->Message as a MySQL warning. */
|
||||
/***********************************************************************/
|
||||
bool PushWarning(PGLOBAL g, PTDBASE tdbp)
|
||||
bool PushWarning(PGLOBAL g, PTDBASE tdbp, int level)
|
||||
{
|
||||
PHC phc;
|
||||
THD *thd;
|
||||
MYCAT *cat= (MYCAT*)tdbp->GetDef()->GetCat();
|
||||
Sql_condition::enum_warning_level wlvl;
|
||||
|
||||
|
||||
if (!cat || !(phc= cat->GetHandler()) || !phc->GetTable() ||
|
||||
!(thd= (phc->GetTable())->in_use))
|
||||
return true;
|
||||
|
||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
|
||||
//push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message);
|
||||
wlvl= (Sql_condition::enum_warning_level)level;
|
||||
push_warning(thd, wlvl, 0, g->Message);
|
||||
return false;
|
||||
} // end of PushWarning
|
||||
|
||||
|
@ -1098,19 +1102,20 @@ PTDB ha_connect::GetTDB(PGLOBAL g)
|
|||
&& (tdbp->GetMode() == xmod
|
||||
|| tdbp->GetAmType() == TYPE_AM_XML)) {
|
||||
tp= tdbp;
|
||||
tp->SetMode(xmod);
|
||||
// tp->SetMode(xmod);
|
||||
} else if ((tp= CntGetTDB(g, table_name, xmod, this)))
|
||||
valid_query_id= xp->last_query_id;
|
||||
else
|
||||
printf("GetTDB: %s\n", g->Message);
|
||||
|
||||
tp->SetMode(xmod);
|
||||
return tp;
|
||||
} // end of GetTDB
|
||||
|
||||
/****************************************************************************/
|
||||
/* Open a CONNECT table, restricting column list if cols is true. */
|
||||
/****************************************************************************/
|
||||
bool ha_connect::OpenTable(PGLOBAL g, bool del)
|
||||
int ha_connect::OpenTable(PGLOBAL g, bool del)
|
||||
{
|
||||
bool rc= false;
|
||||
char *c1= NULL, *c2=NULL;
|
||||
|
@ -1118,11 +1123,11 @@ bool ha_connect::OpenTable(PGLOBAL g, bool del)
|
|||
// Double test to be on the safe side
|
||||
if (!g || !table) {
|
||||
printf("OpenTable logical error; g=%p table=%p\n", g, table);
|
||||
return true;
|
||||
return HA_ERR_INITIALIZATION;
|
||||
} // endif g
|
||||
|
||||
if (!(tdbp= GetTDB(g)))
|
||||
return true;
|
||||
return RC_FX;
|
||||
else if (tdbp->IsReadOnly())
|
||||
switch (xmod) {
|
||||
case MODE_WRITE:
|
||||
|
@ -1130,7 +1135,7 @@ bool ha_connect::OpenTable(PGLOBAL g, bool del)
|
|||
case MODE_UPDATE:
|
||||
case MODE_DELETE:
|
||||
strcpy(g->Message, MSG(READ_ONLY));
|
||||
return true;
|
||||
return HA_ERR_TABLE_READONLY;
|
||||
default:
|
||||
break;
|
||||
} // endswitch xmode
|
||||
|
@ -1207,7 +1212,7 @@ bool ha_connect::OpenTable(PGLOBAL g, bool del)
|
|||
valid_info= false;
|
||||
} // endif rc
|
||||
|
||||
return rc;
|
||||
return (rc) ? HA_ERR_INITIALIZATION : 0;
|
||||
} // end of OpenTable
|
||||
|
||||
|
||||
|
@ -2006,14 +2011,8 @@ int ha_connect::write_row(uchar *buf)
|
|||
if (IsOpened())
|
||||
CloseTable(g);
|
||||
|
||||
if (OpenTable(g)) {
|
||||
if (strstr(g->Message, "read only"))
|
||||
rc= HA_ERR_TABLE_READONLY;
|
||||
else
|
||||
rc= HA_ERR_INITIALIZATION;
|
||||
|
||||
if ((rc= OpenTable(g)))
|
||||
DBUG_RETURN(rc);
|
||||
} // endif tdbp
|
||||
|
||||
} // endif isopened
|
||||
|
||||
|
@ -2378,6 +2377,7 @@ int ha_connect::index_next_same(uchar *buf, const uchar *key, uint keylen)
|
|||
*/
|
||||
int ha_connect::rnd_init(bool scan)
|
||||
{
|
||||
int rc;
|
||||
PGLOBAL g= ((table && table->in_use) ? GetPlug(table->in_use, xp) :
|
||||
(xp) ? xp->g : NULL);
|
||||
DBUG_ENTER("ha_connect::rnd_init");
|
||||
|
@ -2398,8 +2398,8 @@ int ha_connect::rnd_init(bool scan)
|
|||
if (xmod == MODE_UPDATE)
|
||||
bitmap_union(table->read_set, table->write_set);
|
||||
|
||||
if (OpenTable(g, xmod == MODE_DELETE))
|
||||
DBUG_RETURN(HA_ERR_INITIALIZATION);
|
||||
if ((rc= OpenTable(g, xmod == MODE_DELETE)))
|
||||
DBUG_RETURN(rc);
|
||||
|
||||
xp->nrd= xp->fnd= xp->nfd= 0;
|
||||
xp->tb1= my_interval_timer();
|
||||
|
@ -2610,7 +2610,6 @@ int ha_connect::info(uint flag)
|
|||
xp->CheckCleanup();
|
||||
} // endif xmod
|
||||
|
||||
// tdbp= OpenTable(g, xmod == MODE_DELETE);
|
||||
tdbp= GetTDB(g);
|
||||
} // endif tdbp
|
||||
|
||||
|
@ -2705,18 +2704,19 @@ int ha_connect::delete_all_rows()
|
|||
PGLOBAL g= xp->g;
|
||||
DBUG_ENTER("ha_connect::delete_all_rows");
|
||||
|
||||
if (tdbp && tdbp->GetAmType() != TYPE_AM_XML)
|
||||
if (tdbp && tdbp->GetUse() == USE_OPEN &&
|
||||
tdbp->GetAmType() != TYPE_AM_XML &&
|
||||
((PTDBASE)tdbp)->GetFtype() != RECFM_NAF)
|
||||
// Close and reopen the table so it will be deleted
|
||||
rc= CloseTable(g);
|
||||
|
||||
if (!(OpenTable(g))) {
|
||||
if (!(rc= OpenTable(g))) {
|
||||
if (CntDeleteRow(g, tdbp, true)) {
|
||||
printf("%s\n", g->Message);
|
||||
rc= HA_ERR_INTERNAL_ERROR;
|
||||
} // endif
|
||||
|
||||
} else
|
||||
rc= HA_ERR_INITIALIZATION;
|
||||
} // endif rc
|
||||
|
||||
DBUG_RETURN(rc);
|
||||
} // end of delete_all_rows
|
||||
|
|
|
@ -174,7 +174,7 @@ public:
|
|||
bool IsSameIndex(PIXDEF xp1, PIXDEF xp2);
|
||||
|
||||
PTDB GetTDB(PGLOBAL g);
|
||||
bool OpenTable(PGLOBAL g, bool del= false);
|
||||
int OpenTable(PGLOBAL g, bool del= false);
|
||||
bool IsOpened(void);
|
||||
int CloseTable(PGLOBAL g);
|
||||
int MakeRecord(char *buf);
|
||||
|
|
|
@ -48,7 +48,7 @@ salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F',
|
|||
dept INT(4) NOT NULL FIELD_FORMAT='S'
|
||||
) ENGINE=CONNECT TABLE_TYPE=BIN READONLY=Yes FILE_NAME='Testbal.dat';
|
||||
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
ALTER TABLE t1 READONLY=NO;
|
||||
Warnings:
|
||||
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
|
||||
|
@ -84,7 +84,7 @@ t1 CREATE TABLE `t1` (
|
|||
`dept` int(4) NOT NULL `FIELD_FORMAT`='S'
|
||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=BIN `FILE_NAME`='Testbal.dat' `READONLY`=YES
|
||||
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Testing that the underlying file is created
|
||||
|
|
|
@ -50,13 +50,13 @@ children SMALLINT(2) NOT NULL
|
|||
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='people.csv'
|
||||
HEADER=1 SEP_CHAR=';' QUOTED=1 READONLY=yes;
|
||||
INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
UPDATE t1 SET children=6 WHERE name='BILL';
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
DELETE FROM t1 WHERE name='BILL';
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
TRUNCATE TABLE t1;
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
SELECT * FROM t1;
|
||||
name birth children
|
||||
Archibald 2001-05-17 3
|
||||
|
@ -90,7 +90,7 @@ t1 CREATE TABLE `t1` (
|
|||
`children` smallint(2) NOT NULL
|
||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=CSV `FILE_NAME`='people.csv' `HEADER`=1 `SEP_CHAR`=';' `QUOTED`=1 `READONLY`=1
|
||||
INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
SELECT * FROM t1;
|
||||
name birth children
|
||||
Archibald 2001-05-17 3
|
||||
|
|
|
@ -77,13 +77,13 @@ t1 CREATE TABLE `t1` (
|
|||
`a` int(11) NOT NULL
|
||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=DBF `FILE_NAME`='t1.dbf' `READONLY`=Yes
|
||||
INSERT INTO t1 VALUES (30);
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
UPDATE t1 SET a=30 WHERE a=10;
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
DELETE FROM t1 WHERE a=10;
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
TRUNCATE TABLE t1;
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
ALTER TABLE t1 READONLY=NO;
|
||||
Warnings:
|
||||
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
|
||||
|
|
|
@ -30,13 +30,13 @@ t1 CREATE TABLE `t1` (
|
|||
`id` int(11) NOT NULL
|
||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=FIX `FILE_NAME`='t1.txt' `READONLY`=1
|
||||
INSERT INTO t1 VALUES (20);
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
UPDATE t1 SET id=20 WHERE id=10;
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
DELETE FROM t1 WHERE id=10;
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
TRUNCATE TABLE t1;
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
ALTER TABLE t1 READONLY=0;
|
||||
Warnings:
|
||||
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
|
||||
|
|
|
@ -194,13 +194,13 @@ t1 CREATE TABLE `t1` (
|
|||
`c2` char(60) DEFAULT NULL
|
||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=INI `FILE_NAME`='t1.ini' `READONLY`=1
|
||||
INSERT INTO t1 VALUES ('US',40);
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
UPDATE t1 SET c2=20 WHERE c2=10;
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
DELETE FROM t1 WHERE c2=10;
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
TRUNCATE TABLE t1;
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
ALTER TABLE t1 READONLY=0;
|
||||
Warnings:
|
||||
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
|
||||
|
|
|
@ -103,13 +103,13 @@ t1 CREATE TABLE `t1` (
|
|||
`b` char(10) NOT NULL
|
||||
) ENGINE=CONNECT DEFAULT CHARSET=latin1 MAX_ROWS=10 `TABLE_TYPE`=VEC `FILE_NAME`='t1vec' `READONLY`=yes
|
||||
INSERT INTO t1 VALUES (4,'test04');
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
UPDATE t1 SET b='test04' WHERE a=3;
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
DELETE FROM t1 WHERE a=3;
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
TRUNCATE TABLE t1;
|
||||
ERROR HY000: Got error 174 'Cannot modify this read/only protected table' from CONNECT
|
||||
ERROR HY000: Table 't1' is read only
|
||||
ALTER TABLE t1 READONLY=no;
|
||||
Warnings:
|
||||
Warning 1105 The current version of CONNECT did not check what you changed in ALTER. Use at your own risk
|
||||
|
|
|
@ -46,7 +46,7 @@ CREATE TABLE t1
|
|||
salary DOUBLE(9,2) NOT NULL DEFAULT 0.00 FIELD_FORMAT='F',
|
||||
dept INT(4) NOT NULL FIELD_FORMAT='S'
|
||||
) ENGINE=CONNECT TABLE_TYPE=BIN READONLY=Yes FILE_NAME='Testbal.dat';
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
|
||||
ALTER TABLE t1 READONLY=NO;
|
||||
SHOW CREATE TABLE t1;
|
||||
|
@ -54,7 +54,7 @@ INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
|
|||
SELECT * FROM t1;
|
||||
ALTER TABLE t1 READONLY=YES;
|
||||
SHOW CREATE TABLE t1;
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
|
||||
DROP TABLE t1;
|
||||
|
||||
|
|
|
@ -45,13 +45,13 @@ CREATE TABLE t1
|
|||
children SMALLINT(2) NOT NULL
|
||||
) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='people.csv'
|
||||
HEADER=1 SEP_CHAR=';' QUOTED=1 READONLY=yes;
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
UPDATE t1 SET children=6 WHERE name='BILL';
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
DELETE FROM t1 WHERE name='BILL';
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
TRUNCATE TABLE t1;
|
||||
SELECT * FROM t1;
|
||||
ALTER TABLE t1 READONLY=no;
|
||||
|
@ -60,7 +60,7 @@ INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
|
|||
SELECT * FROM t1;
|
||||
ALTER TABLE t1 READONLY=1;
|
||||
SHOW CREATE TABLE t1;
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
INSERT INTO t1 VALUES ('BILL','1973-06-30',5);
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -66,13 +66,13 @@ INSERT INTO t1 VALUES (10),(20);
|
|||
SELECT * FROM t1;
|
||||
ALTER TABLE t1 READONLY=Yes;
|
||||
SHOW CREATE TABLE t1;
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
INSERT INTO t1 VALUES (30);
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
UPDATE t1 SET a=30 WHERE a=10;
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
DELETE FROM t1 WHERE a=10;
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
TRUNCATE TABLE t1;
|
||||
ALTER TABLE t1 READONLY=NO;
|
||||
SHOW CREATE TABLE t1;
|
||||
|
|
|
@ -28,13 +28,13 @@ INSERT INTO t1 VALUES (10);
|
|||
SELECT * FROM t1;
|
||||
ALTER TABLE t1 READONLY=1;
|
||||
SHOW CREATE TABLE t1;
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
INSERT INTO t1 VALUES (20);
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
UPDATE t1 SET id=20 WHERE id=10;
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
DELETE FROM t1 WHERE id=10;
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
TRUNCATE TABLE t1;
|
||||
ALTER TABLE t1 READONLY=0;
|
||||
SHOW CREATE TABLE t1;
|
||||
|
|
|
@ -99,13 +99,13 @@ INSERT INTO t1 VALUES ('UK',10),('FR',20),('RU',30);
|
|||
SELECT * FROM t1;
|
||||
ALTER TABLE t1 READONLY=1;
|
||||
SHOW CREATE TABLE t1;
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
INSERT INTO t1 VALUES ('US',40);
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
UPDATE t1 SET c2=20 WHERE c2=10;
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
DELETE FROM t1 WHERE c2=10;
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
TRUNCATE TABLE t1;
|
||||
ALTER TABLE t1 READONLY=0;
|
||||
SHOW CREATE TABLE t1;
|
||||
|
|
|
@ -52,13 +52,13 @@ SELECT fname, ftype, size FROM dir1 ORDER BY fname, ftype;
|
|||
--echo #
|
||||
ALTER TABLE t1 READONLY=yes;
|
||||
SHOW CREATE TABLE t1;
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
INSERT INTO t1 VALUES (4,'test04');
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
UPDATE t1 SET b='test04' WHERE a=3;
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
DELETE FROM t1 WHERE a=3;
|
||||
--error ER_GET_ERRMSG
|
||||
--error ER_OPEN_AS_READONLY
|
||||
TRUNCATE TABLE t1;
|
||||
ALTER TABLE t1 READONLY=no;
|
||||
SHOW CREATE TABLE t1;
|
||||
|
|
|
@ -873,7 +873,8 @@ ODBConn::ODBConn(PGLOBAL g, TDBODBC *tdbp)
|
|||
m_Connect = NULL;
|
||||
m_Updatable = true;
|
||||
m_Transact = false;
|
||||
m_IDQuoteChar = '\'';
|
||||
m_IDQuoteChar[0] = '"';
|
||||
m_IDQuoteChar[1] = 0;
|
||||
//*m_ErrMsg = '\0';
|
||||
} // end of ODBConn
|
||||
|
||||
|
@ -1232,16 +1233,9 @@ void ODBConn::GetConnectInfo()
|
|||
SQL_MODE_READ_ONLY);
|
||||
#endif // 0
|
||||
|
||||
// Cache the quote char to use when constructing SQL
|
||||
char QuoteChar[2];
|
||||
|
||||
// Get the quote char to use when constructing SQL
|
||||
rc = SQLGetInfo(m_hdbc, SQL_IDENTIFIER_QUOTE_CHAR,
|
||||
QuoteChar, sizeof(QuoteChar), &nResult);
|
||||
|
||||
if (Check(rc) && nResult == 1)
|
||||
m_IDQuoteChar = QuoteChar[0];
|
||||
else
|
||||
m_IDQuoteChar = ' ';
|
||||
m_IDQuoteChar, sizeof(m_IDQuoteChar), &nResult);
|
||||
|
||||
if (trace)
|
||||
htrc("DBMS: %s, Version: %s\n",
|
||||
|
|
|
@ -127,7 +127,7 @@ class ODBConn : public BLOCK {
|
|||
|
||||
// Attributes
|
||||
public:
|
||||
char GetQuoteChar(void) {return m_IDQuoteChar;}
|
||||
char *GetQuoteChar(void) {return m_IDQuoteChar;}
|
||||
// Database successfully opened?
|
||||
bool IsOpen(void) {return m_hdbc != SQL_NULL_HDBC;}
|
||||
PSZ GetStringInfo(ushort infotype);
|
||||
|
@ -184,9 +184,9 @@ class ODBConn : public BLOCK {
|
|||
DWORD m_QueryTimeout;
|
||||
DWORD m_UpdateOptions;
|
||||
DWORD m_RowsetSize;
|
||||
char m_IDQuoteChar[2];
|
||||
int m_Catver;
|
||||
PSZ m_Connect;
|
||||
bool m_Updatable;
|
||||
bool m_Transact;
|
||||
char m_IDQuoteChar;
|
||||
}; // end of ODBConn class definition
|
||||
|
|
|
@ -593,4 +593,4 @@ int global_open(GLOBAL *g, int msgid, const char *filename, int flags, int mode)
|
|||
DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR name, LPCSTR dir);
|
||||
char *MakeEscape(PGLOBAL g, char* str, char q);
|
||||
|
||||
bool PushWarning(PGLOBAL, PTDBASE);
|
||||
bool PushWarning(PGLOBAL, PTDBASE, int level = 1);
|
||||
|
|
|
@ -524,6 +524,7 @@ bool TDBCAT::OpenDB(PGLOBAL g)
|
|||
if (Initialize(g))
|
||||
return true;
|
||||
|
||||
Use = USE_OPEN;
|
||||
return InitCol(g);
|
||||
} // end of OpenDB
|
||||
|
||||
|
|
|
@ -495,6 +495,7 @@ bool TDBOCCUR::OpenDB(PGLOBAL g)
|
|||
if (Tdbp->OpenDB(g))
|
||||
return TRUE;
|
||||
|
||||
Use = USE_OPEN;
|
||||
return ViewColumnList(g);
|
||||
} // end of OpenDB
|
||||
|
||||
|
|
|
@ -90,8 +90,8 @@ extern int num_read, num_there, num_eq[2]; // Statistics
|
|||
/***********************************************************************/
|
||||
ODBCDEF::ODBCDEF(void)
|
||||
{
|
||||
Connect = Tabname = Tabowner = Tabqual = Srcdef = Qchar = Qrystr = NULL;
|
||||
Catver = Options = 0;
|
||||
Connect = Tabname = Tabowner = Tabqual = Srcdef = Qrystr = NULL;
|
||||
Catver = Options = Quoted = 0;
|
||||
Xsrc = false;
|
||||
} // end of ODBCDEF constructor
|
||||
|
||||
|
@ -107,11 +107,11 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
|
|||
Tabowner = Cat->GetStringCatInfo(g, "Owner", "");
|
||||
Tabqual = Cat->GetStringCatInfo(g, "Qualifier", "");
|
||||
Srcdef = Cat->GetStringCatInfo(g, "Srcdef", NULL);
|
||||
Qchar = Cat->GetStringCatInfo(g, "Qchar", "");
|
||||
Qrystr = Cat->GetStringCatInfo(g, "Query_String", "?");
|
||||
Catver = Cat->GetIntCatInfo("Catver", 2);
|
||||
Xsrc = Cat->GetBoolCatInfo("Execsrc", FALSE);
|
||||
Mxr = Cat->GetIntCatInfo("Maxerr", 0);
|
||||
Quoted = Cat->GetIntCatInfo("Quoted", 0);
|
||||
Options = ODBConn::noOdbcDialog;
|
||||
Pseudo = 2; // FILID is Ok but not ROWID
|
||||
return false;
|
||||
|
@ -171,9 +171,9 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp)
|
|||
Owner = tdp->Tabowner;
|
||||
Qualifier = tdp->Tabqual;
|
||||
Srcdef = tdp->Srcdef;
|
||||
Quote = tdp->GetQchar();
|
||||
Qrystr = tdp->Qrystr;
|
||||
Options = tdp->Options;
|
||||
Quoted = max(0, tdp->GetQuoted());
|
||||
Rows = tdp->GetElemt();
|
||||
Catver = tdp->Catver;
|
||||
} else {
|
||||
|
@ -182,13 +182,14 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp)
|
|||
Owner = NULL;
|
||||
Qualifier = NULL;
|
||||
Srcdef = NULL;
|
||||
Quote = NULL;
|
||||
Qrystr = NULL;
|
||||
Options = 0;
|
||||
Quoted = 0;
|
||||
Rows = 0;
|
||||
Catver = 0;
|
||||
} // endif tdp
|
||||
|
||||
Quote = NULL;
|
||||
Query = NULL;
|
||||
Count = NULL;
|
||||
//Where = NULL;
|
||||
|
@ -211,14 +212,15 @@ TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp)
|
|||
Owner = tdbp->Owner;
|
||||
Qualifier = tdbp->Qualifier;
|
||||
Srcdef = tdbp->Srcdef;
|
||||
Quote = tdbp->Quote;
|
||||
Qrystr = tdbp->Qrystr;
|
||||
Quote = tdbp->Quote;
|
||||
Query = tdbp->Query;
|
||||
Count = tdbp->Count;
|
||||
//Where = tdbp->Where;
|
||||
MulConn = tdbp->MulConn;
|
||||
DBQ = tdbp->DBQ;
|
||||
Options = tdbp->Options;
|
||||
Quoted = tdbp->Quoted;
|
||||
Rows = tdbp->Rows;
|
||||
Fpos = tdbp->Fpos;
|
||||
AftRows = tdbp->AftRows;
|
||||
|
@ -445,21 +447,18 @@ char *TDBODBC::MakeSQL(PGLOBAL g, bool cnt)
|
|||
/***********************************************************************/
|
||||
/* MakeInsert: make the Insert statement used with ODBC connection. */
|
||||
/***********************************************************************/
|
||||
bool TDBODBC::MakeInsert(PGLOBAL g)
|
||||
char *TDBODBC::MakeInsert(PGLOBAL g)
|
||||
{
|
||||
char *colist, *valist;
|
||||
char *stmt, *colist, *valist;
|
||||
// char *tk = "`";
|
||||
int len = 0;
|
||||
bool b = FALSE;
|
||||
PCOL colp;
|
||||
|
||||
if (Query)
|
||||
return false; // already done
|
||||
|
||||
for (colp = Columns; colp; colp = colp->GetNext())
|
||||
if (colp->IsSpecial()) {
|
||||
strcpy(g->Message, MSG(NO_ODBC_SPECOL));
|
||||
return true;
|
||||
return NULL;
|
||||
} else {
|
||||
len += (strlen(colp->GetName()) + 4);
|
||||
((PODBCCOL)colp)->Rank = ++Nparm;
|
||||
|
@ -487,18 +486,18 @@ bool TDBODBC::MakeInsert(PGLOBAL g)
|
|||
|
||||
// Below 32 is enough to contain the fixed part of the query
|
||||
len = (strlen(TableName) + strlen(colist) + strlen(valist) + 32);
|
||||
Query = (char*)PlugSubAlloc(g, NULL, len);
|
||||
strcpy(Query, "INSERT INTO ");
|
||||
stmt = (char*)PlugSubAlloc(g, NULL, len);
|
||||
strcpy(stmt, "INSERT INTO ");
|
||||
|
||||
if (Quote)
|
||||
strcat(strcat(strcat(Query, Quote), TableName), Quote);
|
||||
strcat(strcat(strcat(stmt, Quote), TableName), Quote);
|
||||
else
|
||||
strcat(Query, TableName);
|
||||
strcat(stmt, TableName);
|
||||
|
||||
strcat(strcat(strcat(Query, " ("), colist), ") VALUES (");
|
||||
strcat(strcat(Query, valist), ")");
|
||||
strcat(strcat(strcat(stmt, " ("), colist), ") VALUES (");
|
||||
strcat(strcat(stmt, valist), ")");
|
||||
|
||||
return false;
|
||||
return stmt;
|
||||
} // end of MakeInsert
|
||||
|
||||
/***********************************************************************/
|
||||
|
@ -520,27 +519,58 @@ bool TDBODBC::BindParameters(PGLOBAL g)
|
|||
} // end of BindParameters
|
||||
|
||||
/***********************************************************************/
|
||||
/* MakeCMD: make the SQL statement to send to ODBC connection. */
|
||||
/* MakeUpdate: make the SQL statement to send to ODBC connection. */
|
||||
/***********************************************************************/
|
||||
char *TDBODBC::MakeStmt(PGLOBAL g)
|
||||
char *TDBODBC::MakeUpdate(PGLOBAL g)
|
||||
{
|
||||
char *qc, *stmt = NULL, cmd[8], tab[96], end[512];
|
||||
int n = (Mode == MODE_DELETE) ? 1 : 2;
|
||||
char *qc, *stmt = NULL, cmd[8], tab[96], end[1024];
|
||||
|
||||
stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
|
||||
*end = 0;
|
||||
qc = (Quote) ? Quote : "\"";
|
||||
memset(end, 0, sizeof(end));
|
||||
|
||||
if (sscanf(Qrystr, "%s `%[^`]`%511c", cmd, tab, end) > n ||
|
||||
sscanf(Qrystr, "%s \"%[^\"]\"%511c", cmd, tab, end) > n ||
|
||||
sscanf(Qrystr, "%s %s%511c", cmd, tab, end) > n)
|
||||
strcat(strcat(strcpy(tab, qc), TableName), qc);
|
||||
if (sscanf(Qrystr, "%s `%[^`]`%1023c", cmd, tab, end) > 2 ||
|
||||
sscanf(Qrystr, "%s \"%[^\"]\"%1023c", cmd, tab, end) > 2)
|
||||
qc = Ocp->GetQuoteChar();
|
||||
else if (sscanf(Qrystr, "%s %s%1023c", cmd, tab, end) > 2)
|
||||
qc = (Quoted) ? Quote : "";
|
||||
else {
|
||||
strcpy(g->Message, "Cannot use this UPDATE/DELETE command");
|
||||
strcpy(g->Message, "Cannot use this UPDATE command");
|
||||
return NULL;
|
||||
} // endif sscanf
|
||||
|
||||
strcat(strcat(strcpy(stmt, cmd), " "), tab);
|
||||
assert(!stricmp(cmd, "update"));
|
||||
strcat(strcat(strcat(strcpy(stmt, "UPDATE "), qc), TableName), qc);
|
||||
|
||||
for (int i = 0; end[i]; i++)
|
||||
if (end[i] == '`')
|
||||
end[i] = *qc;
|
||||
|
||||
strcat(stmt, end);
|
||||
return stmt;
|
||||
} // end of MakeUpdate
|
||||
|
||||
/***********************************************************************/
|
||||
/* MakeDelete: make the SQL statement to send to ODBC connection. */
|
||||
/***********************************************************************/
|
||||
char *TDBODBC::MakeDelete(PGLOBAL g)
|
||||
{
|
||||
char *qc, *stmt = NULL, cmd[8], from[8], tab[96], end[512];
|
||||
|
||||
stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
|
||||
memset(end, 0, sizeof(end));
|
||||
|
||||
if (sscanf(Qrystr, "%s %s `%[^`]`%511c", cmd, from, tab, end) > 2 ||
|
||||
sscanf(Qrystr, "%s %s \"%[^\"]\"%511c", cmd, from, tab, end) > 2)
|
||||
qc = Ocp->GetQuoteChar();
|
||||
else if (sscanf(Qrystr, "%s %s %s%511c", cmd, from, tab, end) > 2)
|
||||
qc = (Quoted) ? Quote : "";
|
||||
else {
|
||||
strcpy(g->Message, "Cannot use this DELETE command");
|
||||
return NULL;
|
||||
} // endif sscanf
|
||||
|
||||
assert(!stricmp(cmd, "delete") && !stricmp(from, "from"));
|
||||
strcat(strcat(strcat(strcpy(stmt, "DELETE FROM "), qc), TableName), qc);
|
||||
|
||||
if (*end) {
|
||||
for (int i = 0; end[i]; i++)
|
||||
|
@ -551,7 +581,7 @@ char *TDBODBC::MakeStmt(PGLOBAL g)
|
|||
} // endif end
|
||||
|
||||
return stmt;
|
||||
} // end of MakeStmt
|
||||
} // end of MakeDelete
|
||||
|
||||
/***********************************************************************/
|
||||
/* ResetSize: call by TDBMUL when calculating size estimate. */
|
||||
|
@ -572,7 +602,7 @@ int TDBODBC::GetMaxSize(PGLOBAL g)
|
|||
{
|
||||
if (MaxSize < 0) {
|
||||
// Make MariaDB happy
|
||||
MaxSize = 100;
|
||||
MaxSize = (Mode == MODE_READ) ? 100 : 0;
|
||||
#if 0
|
||||
// This is unuseful and takes time
|
||||
if (Srcdef) {
|
||||
|
@ -655,51 +685,42 @@ bool TDBODBC::OpenDB(PGLOBAL g)
|
|||
|
||||
if (Ocp->Open(Connect, Options) < 1)
|
||||
return true;
|
||||
else if (Quoted)
|
||||
Quote = Ocp->GetQuoteChar();
|
||||
|
||||
Use = USE_OPEN; // Do it now in case we are recursively called
|
||||
|
||||
/*********************************************************************/
|
||||
/* Allocate whatever is used for getting results. */
|
||||
/* Make the command and allocate whatever is used for getting results. */
|
||||
/*********************************************************************/
|
||||
if (Mode == MODE_READ) {
|
||||
/*******************************************************************/
|
||||
/* The issue here is that if max result size is needed, it must be */
|
||||
/* calculated before the result set for the final data retrieval is*/
|
||||
/* allocated and the final statement prepared so we call GetMaxSize*/
|
||||
/* here. It can be a waste of time if the max size is not needed */
|
||||
/* but currently we always are asking for it (for progress info). */
|
||||
/*******************************************************************/
|
||||
GetMaxSize(g); // Will be set for next call
|
||||
|
||||
if (!Query)
|
||||
if ((Query = MakeSQL(g, false))) {
|
||||
for (PODBCCOL colp = (PODBCCOL)Columns;
|
||||
colp; colp = (PODBCCOL)colp->GetNext())
|
||||
for (PODBCCOL colp = (PODBCCOL)Columns; colp;
|
||||
colp = (PODBCCOL)colp->GetNext())
|
||||
if (!colp->IsSpecial())
|
||||
colp->AllocateBuffers(g, Rows);
|
||||
|
||||
} else {
|
||||
Ocp->Close();
|
||||
return true;
|
||||
rc = ((Rows = Ocp->ExecDirectSQL(Query, (PODBCCOL)Columns)) < 0);
|
||||
} // endif Query
|
||||
|
||||
if (!rc)
|
||||
rc = ((Rows = Ocp->ExecDirectSQL(Query, (PODBCCOL)Columns)) < 0);
|
||||
|
||||
} else if (Mode == MODE_INSERT) {
|
||||
if (!(rc = MakeInsert(g)))
|
||||
if ((Query = MakeInsert(g))) {
|
||||
if (Nparm != Ocp->PrepareSQL(Query)) {
|
||||
strcpy(g->Message, MSG(PARM_CNT_MISS));
|
||||
rc = true;
|
||||
} else
|
||||
rc = BindParameters(g);
|
||||
|
||||
} else {
|
||||
strcpy(g->Message, "No DELETE/UPDATE of ODBC tablesd");
|
||||
return true;
|
||||
} // endelse
|
||||
} // endif Query
|
||||
|
||||
if (rc) {
|
||||
} else if (Mode == MODE_UPDATE)
|
||||
Query = MakeUpdate(g);
|
||||
else if (Mode == MODE_DELETE)
|
||||
Query = MakeDelete(g);
|
||||
else
|
||||
sprintf(g->Message, "Invalid mode %d", Mode);
|
||||
|
||||
if (!Query || rc) {
|
||||
Ocp->Close();
|
||||
return true;
|
||||
} // endif rc
|
||||
|
@ -730,6 +751,21 @@ int TDBODBC::ReadDB(PGLOBAL g)
|
|||
htrc("ODBC ReadDB: R%d Mode=%d key=%p link=%p Kindex=%p\n",
|
||||
GetTdb_No(), Mode, To_Key_Col, To_Link, To_Kindex);
|
||||
|
||||
if (Mode == MODE_UPDATE || Mode == MODE_DELETE) {
|
||||
// Send the UPDATE/DELETE command to the remote table
|
||||
if (!Ocp->ExecSQLcommand(Query)) {
|
||||
sprintf(g->Message, "%s: %d affected rows", TableName, AftRows);
|
||||
|
||||
if (trace)
|
||||
htrc("%s\n", g->Message);
|
||||
|
||||
PushWarning(g, this, 0); // 0 means a Note
|
||||
return RC_EF; // Nothing else to do
|
||||
} else
|
||||
return RC_FX; // Error
|
||||
|
||||
} // endif Mode
|
||||
|
||||
if (To_Kindex) {
|
||||
// Direct access of ODBC tables is not implemented yet
|
||||
strcpy(g->Message, MSG(NO_ODBC_DIRECT));
|
||||
|
@ -775,8 +811,22 @@ int TDBODBC::WriteDB(PGLOBAL g)
|
|||
/***********************************************************************/
|
||||
int TDBODBC::DeleteDB(PGLOBAL g, int irc)
|
||||
{
|
||||
strcpy(g->Message, MSG(NO_ODBC_DELETE));
|
||||
return RC_FX;
|
||||
if (irc == RC_FX) {
|
||||
// Send the DELETE (all) command to the remote table
|
||||
if (!Ocp->ExecSQLcommand(Query)) {
|
||||
sprintf(g->Message, "%s: %d affected rows", TableName, AftRows);
|
||||
|
||||
if (trace)
|
||||
htrc("%s\n", g->Message);
|
||||
|
||||
PushWarning(g, this, 0); // 0 means a Note
|
||||
return RC_OK; // This is a delete all
|
||||
} else
|
||||
return RC_FX; // Error
|
||||
|
||||
} else
|
||||
return RC_OK; // Ignore
|
||||
|
||||
} // end of DeleteDB
|
||||
|
||||
/***********************************************************************/
|
||||
|
@ -790,6 +840,7 @@ void TDBODBC::CloseDB(PGLOBAL g)
|
|||
// } // endif
|
||||
|
||||
if (Ocp)
|
||||
|
||||
Ocp->Close();
|
||||
|
||||
if (trace)
|
||||
|
@ -1226,6 +1277,15 @@ int TDBXDBC::WriteDB(PGLOBAL g)
|
|||
return RC_FX;
|
||||
} // end of DeleteDB
|
||||
|
||||
/***********************************************************************/
|
||||
/* Data Base delete line routine for ODBC access method. */
|
||||
/***********************************************************************/
|
||||
int TDBXDBC::DeleteDB(PGLOBAL g, int irc)
|
||||
{
|
||||
strcpy(g->Message, MSG(NO_ODBC_DELETE));
|
||||
return RC_FX;
|
||||
} // end of DeleteDB
|
||||
|
||||
/* --------------------------- XSRCCOL ------------------------------- */
|
||||
|
||||
/***********************************************************************/
|
||||
|
|
|
@ -34,7 +34,7 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
|
|||
PSZ GetTabowner(void) {return Tabowner;}
|
||||
PSZ GetTabqual(void) {return Tabqual;}
|
||||
PSZ GetSrcdef(void) {return Srcdef;}
|
||||
PSZ GetQchar(void) {return (Qchar && *Qchar) ? Qchar : NULL;}
|
||||
int GetQuoted(void) {return Quoted;}
|
||||
int GetCatver(void) {return Catver;}
|
||||
int GetOptions(void) {return Options;}
|
||||
|
||||
|
@ -53,6 +53,7 @@ class DllExport ODBCDEF : public TABDEF { /* Logical table description */
|
|||
PSZ Qrystr; /* The original query */
|
||||
int Catver; /* ODBC version for catalog functions */
|
||||
int Options; /* Open connection options */
|
||||
int Quoted; /* Identifier quoting level */
|
||||
int Mxr; /* Maxerr for an Exec table */
|
||||
bool Xsrc; /* Execution type */
|
||||
}; // end of ODBCDEF
|
||||
|
@ -100,10 +101,11 @@ class TDBODBC : public TDBASE {
|
|||
// Internal functions
|
||||
int Decode(char *utf, char *buf, size_t n);
|
||||
char *MakeSQL(PGLOBAL g, bool cnt);
|
||||
bool MakeInsert(PGLOBAL g);
|
||||
char *MakeInsert(PGLOBAL g);
|
||||
//bool MakeFilter(PGLOBAL g, bool c);
|
||||
bool BindParameters(PGLOBAL g);
|
||||
char *MakeStmt(PGLOBAL g);
|
||||
char *MakeUpdate(PGLOBAL g);
|
||||
char *MakeDelete(PGLOBAL g);
|
||||
|
||||
// Members
|
||||
ODBConn *Ocp; // Points to an ODBC connection class
|
||||
|
@ -121,6 +123,7 @@ class TDBODBC : public TDBASE {
|
|||
char *DBQ; // The address part of Connect string
|
||||
char *Qrystr; // The original query
|
||||
int Options; // Connect options
|
||||
int Quoted; // The identifier quoting level
|
||||
int Fpos; // Position of last read record
|
||||
int AftRows; // The number of affected rows
|
||||
int Rows; // Rowset size
|
||||
|
@ -206,7 +209,7 @@ class TDBXDBC : public TDBODBC {
|
|||
virtual bool OpenDB(PGLOBAL g);
|
||||
virtual int ReadDB(PGLOBAL g);
|
||||
virtual int WriteDB(PGLOBAL g);
|
||||
//virtual int DeleteDB(PGLOBAL g, int irc);
|
||||
virtual int DeleteDB(PGLOBAL g, int irc);
|
||||
//virtual void CloseDB(PGLOBAL g);
|
||||
|
||||
protected:
|
||||
|
|
|
@ -607,6 +607,8 @@ bool TDBPIVOT::OpenDB(PGLOBAL g)
|
|||
if (Tdbp->OpenDB(g))
|
||||
return TRUE;
|
||||
|
||||
Use = USE_OPEN; // Do it now in case we are recursively called
|
||||
|
||||
/*********************************************************************/
|
||||
/* Make all required pivot columns for object views. */
|
||||
/*********************************************************************/
|
||||
|
|
|
@ -495,6 +495,7 @@ bool TDBPRX::OpenDB(PGLOBAL g)
|
|||
if (Tdbp->OpenDB(g))
|
||||
return TRUE;
|
||||
|
||||
Use = USE_OPEN;
|
||||
return FALSE;
|
||||
} // end of OpenDB
|
||||
|
||||
|
|
|
@ -667,6 +667,8 @@ bool TDBWMI::OpenDB(PGLOBAL g)
|
|||
} else
|
||||
DoubleSlash(g);
|
||||
|
||||
Use = USE_OPEN; // Do it now in case we are recursively called
|
||||
|
||||
/*********************************************************************/
|
||||
/* Initialize the WMI processing. */
|
||||
/*********************************************************************/
|
||||
|
|
|
@ -193,6 +193,7 @@ bool TDBXCL::OpenDB(PGLOBAL g)
|
|||
if (Tdbp->OpenDB(g))
|
||||
return TRUE;
|
||||
|
||||
Use = USE_OPEN;
|
||||
return FALSE;
|
||||
} // end of OpenDB
|
||||
|
||||
|
|
Loading…
Reference in a new issue