Commit 5d831196 authored by Olivier Bertrand's avatar Olivier Bertrand

- Implement the NEWMSG and XMSG methods

  They are still experimental and should not be used in production.
added:
  storage/connect/encas.h
  storage/connect/english.msg
  storage/connect/enids.h
  storage/connect/frcas.h
  storage/connect/french.msg
  storage/connect/frids.h
  storage/connect/frmsg.h
modified:
  storage/connect/connect.cc
  storage/connect/engmsg.h
  storage/connect/filamdbf.cpp
  storage/connect/global.h
  storage/connect/ha_connect.cc
  storage/connect/msgid.h
  storage/connect/plgdbutl.cpp
  storage/connect/plugutil.c
  storage/connect/rcmsg.c
  storage/connect/resource.h
  storage/connect/tabfmt.h

- Fix global variable not being properly initialized (MDEV-6690, MDEV-7094)
modified:
  storage/connect/ha_connect.cc
  storage/connect/plugutil.c
  storage/connect/user_connect.cc
  storage/connect/xindex.cpp

- Implement Rewind for ODBC tables (MDEV-7097)
modified:
  storage/connect/odbconn.cpp
  storage/connect/odbconn.h
  storage/connect/tabmysql.cpp
  storage/connect/tabodbc.cpp

- Reset N when reopening MYSQL tables
modified:
  storage/connect/tabmysql.cpp
parent 9ade2d08
......@@ -281,7 +281,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2,
if (!colp && !(mode == MODE_INSERT && tdbp->IsSpecial(p))) {
if (g->Message[0] == 0)
sprintf(g->Message, "Column %s not found in %s", p, tdbp->GetName());
sprintf(g->Message, MSG(COL_ISNOT_TABLE), p, tdbp->GetName());
goto err;
} // endif colp
......@@ -651,7 +651,7 @@ int CntIndexInit(PGLOBAL g, PTDB ptdb, int id, bool sorted)
if (!ptdb)
return -1;
else if (!((PTDBASE)ptdb)->GetDef()->Indexable()) {
sprintf(g->Message, "CntIndexInit: Table %s is not indexable", ptdb->GetName());
sprintf(g->Message, MSG(TABLE_NO_INDEX), ptdb->GetName());
return 0;
} else if (((PTDBASE)ptdb)->GetDef()->Indexable() == 3) {
return 1;
......@@ -724,7 +724,7 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op,
x= ((PTDBASE)ptdb)->GetDef()->Indexable();
if (!x) {
sprintf(g->Message, "CntIndexRead: Table %s is not indexable", ptdb->GetName());
sprintf(g->Message, MSG(TABLE_NO_INDEX), ptdb->GetName());
return RC_FX;
} else if (x == 2) {
// Remote index
......@@ -838,7 +838,7 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len,
x= ((PTDBASE)ptdb)->GetDef()->Indexable();
if (!x) {
sprintf(g->Message, "CntIndexRange: Table %s is not indexable", ptdb->GetName());
sprintf(g->Message, MSG(TABLE_NO_INDEX), ptdb->GetName());
DBUG_PRINT("Range", ("%s", g->Message));
return -1;
} else if (x == 2) {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
case IDS_TABLES: p = "Table Headers"; break;
case IDS_TAB_01: p = "Table_Cat"; break;
case IDS_TAB_02: p = "Table_Schema"; break;
case IDS_TAB_03: p = "Table_Name"; break;
case IDS_TAB_04: p = "Table_Type"; break;
case IDS_TAB_05: p = "Remark"; break;
case IDS_COLUMNS: p = "Column Headers"; break;
case IDS_COL_01: p = "Table_Cat"; break;
case IDS_COL_02: p = "Table_Schema"; break;
case IDS_COL_03: p = "Table_Name"; break;
case IDS_COL_04: p = "Column_Name"; break;
case IDS_COL_05: p = "Data_Type"; break;
case IDS_COL_06: p = "Type_Name"; break;
case IDS_COL_07: p = "Column_Size"; break;
case IDS_COL_08: p = "Buffer_Length"; break;
case IDS_COL_09: p = "Decimal_Digits"; break;
case IDS_COL_10: p = "Radix"; break;
case IDS_COL_11: p = "Nullable"; break;
case IDS_COL_12: p = "Remarks"; break;
case IDS_PKEY: p = "Key Headers"; break;
case IDS_PKY_01: p = "Table_Catalog"; break;
case IDS_PKY_02: p = "Table_Schema"; break;
case IDS_PKY_03: p = "Table_Name"; break;
case IDS_PKY_04: p = "Column_Name"; break;
case IDS_PKY_05: p = "Key_Seq"; break;
case IDS_PKY_06: p = "Pk_Name"; break;
case IDS_STAT: p = "Stat Headers"; break;
case IDS_STA_01: p = "Table_Catalog"; break;
case IDS_STA_02: p = "Table_Schema"; break;
case IDS_STA_03: p = "Table_Name"; break;
case IDS_STA_04: p = "Non_Unique"; break;
case IDS_STA_05: p = "Index_Qualifier"; break;
case IDS_STA_06: p = "Index_Name"; break;
case IDS_STA_07: p = "Type"; break;
case IDS_STA_08: p = "Seq_in_Index"; break;
case IDS_STA_09: p = "Column_Name"; break;
case IDS_STA_10: p = "Collation"; break;
case IDS_STA_11: p = "Cardinality"; break;
case IDS_STA_12: p = "Pages"; break;
case IDS_STA_13: p = "Filter_Condition"; break;
case IDS_DRIVER: p = "Driver Headers"; break;
case IDS_DRV_01: p = "Description"; break;
case IDS_DRV_02: p = "Attributes"; break;
case IDS_DSRC: p = "DataSrc Headers"; break;
case IDS_DSC_01: p = "Name"; break;
case IDS_DSC_02: p = "Description"; break;
......@@ -284,7 +284,8 @@ PQRYRES DBFColumns(PGLOBAL g, char *dp, const char *fn, bool info)
break;
default:
if (!info) {
sprintf(g->Message, MSG(BAD_DBF_TYPE), thisfield.Type);
sprintf(g->Message, MSG(BAD_DBF_TYPE), thisfield.Type
, thisfield.Name);
goto err;
} // endif info
......@@ -585,7 +586,7 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)
case 'D': // Date
break;
default: // Should never happen
sprintf(g->Message, "Unsupported DBF type %c for column %s",
sprintf(g->Message, MSG(BAD_DBF_TYPE),
c, cdp->GetName());
return true;
} // endswitch c
......
This diff is collapsed.
This diff is collapsed.
case IDS_TABLES: p = "Table Enttes"; break;
case IDS_TAB_01: p = "Catalogue"; break;
case IDS_TAB_02: p = "Schma"; break;
case IDS_TAB_03: p = "Nom"; break;
case IDS_TAB_04: p = "Type"; break;
case IDS_TAB_05: p = "Remarque"; break;
case IDS_COLUMNS: p = "Colonne Enttes"; break;
case IDS_COL_01: p = "Cat_Table"; break;
case IDS_COL_02: p = "Schem_Table"; break;
case IDS_COL_03: p = "Nom_Table"; break;
case IDS_COL_04: p = "Nom_Colonne"; break;
case IDS_COL_05: p = "Type_Donnes"; break;
case IDS_COL_06: p = "Nom_Type"; break;
case IDS_COL_07: p = "Prcision"; break;
case IDS_COL_08: p = "Longueur"; break;
case IDS_COL_09: p = "Echelle"; break;
case IDS_COL_10: p = "Base"; break;
case IDS_COL_11: p = "Nullifiable"; break;
case IDS_COL_12: p = "Remarques"; break;
case IDS_PKEY: p = "Cl Enttes"; break;
case IDS_PKY_01: p = "Cat_Table"; break;
case IDS_PKY_02: p = "Schem_Table"; break;
case IDS_PKY_03: p = "Nom_Table"; break;
case IDS_PKY_04: p = "Nom_Colonne"; break;
case IDS_PKY_05: p = "Numro_Cl"; break;
case IDS_PKY_06: p = "Nom_Cl"; break;
case IDS_STAT: p = "Stat Enttes"; break;
case IDS_STA_01: p = "Table_Catalog"; break;
case IDS_STA_02: p = "Table_Schema"; break;
case IDS_STA_03: p = "Table_Name"; break;
case IDS_STA_04: p = "Non_Unique"; break;
case IDS_STA_05: p = "Index_Qualifier"; break;
case IDS_STA_06: p = "Index_Name"; break;
case IDS_STA_07: p = "Type"; break;
case IDS_STA_08: p = "Seq_in_Index"; break;
case IDS_STA_09: p = "Column_Name"; break;
case IDS_STA_10: p = "Collation"; break;
case IDS_STA_11: p = "Cardinality"; break;
case IDS_STA_12: p = "Pages"; break;
case IDS_STA_13: p = "Filter_Condition"; break;
case IDS_DRIVER: p = "Driver Enttes"; break;
case IDS_DRV_01: p = "Description"; break;
case IDS_DRV_02: p = "Attributs"; break;
case IDS_DSRC: p = "DataSrc Enttes"; break;
case IDS_DSC_01: p = "Nom"; break;
case IDS_DSC_02: p = "Description"; break;
This diff is collapsed.
......@@ -24,13 +24,13 @@
#endif
#if defined(XMSG)
#error Option XMSG is not yet fully implemented
//#error Option XMSG is not yet fully implemented
// Definition used to read messages from message file.
#include "msgid.h"
#define MSG(I) PlugReadMessage(NULL, MSG_##I, #I)
#define STEP(I) PlugReadMessage(g, MSG_##I, #I)
#elif defined(NEWMSG)
#error Option NEWMSG is not yet fully implemented
//#error Option NEWMSG is not yet fully implemented
// Definition used to get messages from resource.
#include "msgid.h"
#define MSG(I) PlugGetMessage(NULL, MSG_##I)
......
......@@ -179,25 +179,25 @@ extern "C" {
char slash= '/';
#endif // !WIN32
// int trace= 0; // The general trace value
int xconv= 0; // The type conversion option
int zconv= SZCONV; // The text conversion size
// int trace= 0; // The general trace value
ulong xconv= 0; // The type conversion option
int zconv= 0; // The text conversion size
} // extern "C"
#if defined(XMAP)
bool xmap= false;
my_bool xmap= false;
#endif // XMAP
uint worksize= SZWORK;
// uint worksize= 0;
ulong ha_connect::num= 0;
//int DTVAL::Shift= 0;
/* CONNECT system variables */
static int conv_size= SZCONV;
static uint work_size= SZWORK;
static ulong type_conv= 0;
//atic int conv_size= 0;
//atic uint work_size= 0;
//atic ulong type_conv= 0;
#if defined(XMAP)
static my_bool indx_map= 0;
//atic my_bool indx_map= 0;
#endif // XMAP
#if defined(XMSG)
extern "C" {
......@@ -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);
uint GetWorkSize(void);
void SetWorkSize(uint);
static PCONNECT GetUser(THD *thd, PCONNECT xp);
static PGLOBAL GetPlug(THD *thd, PCONNECT& lxp);
......@@ -280,7 +282,13 @@ static MYSQL_THDVAR_ENUM(
1, // def (AUTO)
&usetemp_typelib); // typelib
#if defined(XMSG)
// Size used for g->Sarea_Size
static MYSQL_THDVAR_UINT(work_size,
PLUGIN_VAR_RQCMDARG,
"Size of the CONNECT work area.",
NULL, NULL, SZWORK, SZWMIN, UINT_MAX, 1);
#if defined(XMSG) || defined(NEWMSG)
const char *language_names[]=
{
"default", "english", "french", NullS
......@@ -300,7 +308,7 @@ static MYSQL_THDVAR_ENUM(
NULL, // update
1, // def (ENGLISH)
&language_typelib); // typelib
#endif // XMSG
#endif // XMSG || NEWMSG
/***********************************************************************/
/* Function to export session variable values to other source files. */
......@@ -308,13 +316,31 @@ 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);}
#if defined(XMSG)
uint GetWorkSize(void) {return THDVAR(current_thd, work_size);}
void SetWorkSize(uint n)
{
// Changing the session variable value seems to be impossible here
// and should be done in a check function
push_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, 0,
"Work size too big, try setting a smaller value");
} // end of SetWorkSize
#if defined(XMSG) || defined(NEWMSG)
extern "C" const char *msglang(void)
{
return language_names[THDVAR(current_thd, msg_lang)];
} // end of msglang
#endif // XMSG
#else // !XMSG && !NEWMSG
extern "C" const char *msglang(void)
{
#if defined(FRENCH)
return "french";
#else // DEFAULT
return "english";
#endif // DEFAULT
} // end of msglang
#endif // !XMSG && !NEWMSG
#if 0
/***********************************************************************/
/* Global variables update functions. */
/***********************************************************************/
......@@ -332,21 +358,57 @@ static void update_connect_xconv(MYSQL_THD thd,
xconv= (int)(*(ulong *)var_ptr= *(ulong *)save);
} // end of update_connect_xconv
static void update_connect_worksize(MYSQL_THD thd,
struct st_mysql_sys_var *var,
void *var_ptr, const void *save)
{
worksize= (uint)(*(ulong *)var_ptr= *(ulong *)save);
} // end of update_connect_worksize
#if defined(XMAP)
static void update_connect_xmap(MYSQL_THD thd,
struct st_mysql_sys_var *var,
void *var_ptr, const void *save)
{
xmap= (bool)(*(my_bool *)var_ptr= *(my_bool *)save);
xmap= (my_bool)(*(my_bool *)var_ptr= *(my_bool *)save);
} // end of update_connect_xmap
#endif // XMAP
#endif // 0
#if 0 // (was XMSG) Unuseful because not called for default value
static void update_msg_path(MYSQL_THD thd,
struct st_mysql_sys_var *var,
void *var_ptr, const void *save)
{
char *value= *(char**)save;
char *old= *(char**)var_ptr;
if (value)
*(char**)var_ptr= my_strdup(value, MYF(0));
else
*(char**)var_ptr= 0;
my_free(old);
} // end of update_msg_path
static int check_msg_path (MYSQL_THD thd, struct st_mysql_sys_var *var,
void *save, struct st_mysql_value *value)
{
const char *path;
char buff[512];
int len= sizeof(buff);
path= value->val_str(value, buff, &len);
if (path && *path != '*') {
/* Save a pointer to the name in the
'file_format_name_map' constant array. */
*(char**)save= my_strdup(path, MYF(0));
return(0);
} else {
push_warning_printf(thd,
Sql_condition::WARN_LEVEL_WARN,
ER_WRONG_ARGUMENTS,
"CONNECT: invalid message path");
} // endif path
*(char**)save= NULL;
return(1);
} // end of check_msg_path
#endif // 0
/***********************************************************************/
/* The CONNECT handlerton object. */
......@@ -6237,15 +6299,15 @@ struct st_mysql_storage_engine connect_storage_engine=
/***********************************************************************/
// Size used when converting TEXT columns to VARCHAR
#if defined(_DEBUG)
static MYSQL_SYSVAR_INT(conv_size, conv_size,
static MYSQL_SYSVAR_INT(conv_size, zconv,
PLUGIN_VAR_RQCMDARG, // opt
"Size used when converting TEXT columns.",
NULL, update_connect_zconv, SZCONV, 0, 65500, 1);
NULL, NULL, SZCONV, 0, 65500, 1);
#else
static MYSQL_SYSVAR_INT(conv_size, conv_size,
static MYSQL_SYSVAR_INT(conv_size, zconv,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, // opt
"Size used when converting TEXT columns.",
NULL, update_connect_zconv, SZCONV, 0, 65500, 1);
NULL, NULL, SZCONV, 0, 65500, 1);
#endif
/**
......@@ -6268,45 +6330,41 @@ TYPELIB xconv_typelib=
#if defined(_DEBUG)
static MYSQL_SYSVAR_ENUM(
type_conv, // name
type_conv, // varname
xconv, // varname
PLUGIN_VAR_RQCMDARG, // opt
"Unsupported types conversion.", // comment
NULL, // check
update_connect_xconv, // update function
NULL, // update function
0, // def (no)
&xconv_typelib); // typelib
#else
static MYSQL_SYSVAR_ENUM(
type_conv, // name
type_conv, // varname
xconv, // varname
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"Unsupported types conversion.", // comment
NULL, // check
update_connect_xconv, // update function
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, indx_map, PLUGIN_VAR_RQCMDARG,
"Using file mapping for indexes",
NULL, update_connect_xmap, 0);
static MYSQL_SYSVAR_BOOL(indx_map, xmap, PLUGIN_VAR_RQCMDARG,
"Using file mapping for indexes", NULL, NULL, 0);
#endif // XMAP
#if defined(XMSG)
static MYSQL_SYSVAR_STR(errmsg_dir_path, msg_path,
// PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"Path to the directory where are the message files",
NULL, NULL, "");
// check_msg_path, update_msg_path,
NULL, NULL,
"../../../../storage/connect/"); // for testing
#endif // XMSG
// Size used for g->Sarea_Size
static MYSQL_SYSVAR_UINT(work_size, work_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"Size of the CONNECT work area.",
NULL, update_connect_worksize, SZWORK, SZWMIN, UINT_MAX, 1);
static struct st_mysql_sys_var* connect_system_variables[]= {
MYSQL_SYSVAR(xtrace),
MYSQL_SYSVAR(conv_size),
......@@ -6317,8 +6375,10 @@ static struct st_mysql_sys_var* connect_system_variables[]= {
MYSQL_SYSVAR(work_size),
MYSQL_SYSVAR(use_tempfile),
MYSQL_SYSVAR(exact_info),
#if defined(XMSG)
#if defined(XMSG) || defined(NEWMSG)
MYSQL_SYSVAR(msg_lang),
#endif // XMSG || NEWMSG
#if defined(XMSG)
MYSQL_SYSVAR(errmsg_dir_path),
#endif // XMSG
NULL
......
This diff is collapsed.
/************ Odbconn C++ Functions Source Code File (.CPP) ************/
/* Name: ODBCONN.CPP Version 1.9 */
/* Name: ODBCONN.CPP Version 2.0 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 1998-2013 */
/* (C) Copyright to the author Olivier BERTRAND 1998-2014 */
/* */
/* This file contains the ODBC connection classes functions. */
/***********************************************************************/
......@@ -830,7 +830,7 @@ DBX::DBX(RETCODE rc, PSZ msg)
/***********************************************************************/
/* This function is called by ThrowDBX. */
/***********************************************************************/
void DBX::BuildErrorMessage(ODBConn* pdb, HSTMT hstmt)
bool DBX::BuildErrorMessage(ODBConn* pdb, HSTMT hstmt)
{
if (pdb) {
SWORD len;
......@@ -843,7 +843,9 @@ void DBX::BuildErrorMessage(ODBConn* pdb, HSTMT hstmt)
rc = SQLError(pdb->m_henv, pdb->m_hdbc, hstmt, state,
&native, msg, SQL_MAX_MESSAGE_LENGTH - 1, &len);
if (rc != SQL_INVALID_HANDLE) {
if (rc == SQL_NO_DATA_FOUND)
return false;
else if (rc != SQL_INVALID_HANDLE) {
// Skip non-errors
for (int i = 0; i < MAX_NUM_OF_MSG
&& (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
......@@ -859,7 +861,7 @@ void DBX::BuildErrorMessage(ODBConn* pdb, HSTMT hstmt)
} // endfor i
return;
return true;
} else {
snprintf((char*)msg, SQL_MAX_MESSAGE_LENGTH + 1, "%s: %s", m_Msg,
MSG(BAD_HANDLE_VAL));
......@@ -869,7 +871,7 @@ void DBX::BuildErrorMessage(ODBConn* pdb, HSTMT hstmt)
if (trace)
htrc("%s: rc=%hd\n", SVP(m_ErrMsg[0]), m_RC);
return;
return true;
} // endif rc
} else
......@@ -878,6 +880,7 @@ void DBX::BuildErrorMessage(ODBConn* pdb, HSTMT hstmt)
if (trace)
htrc("%s: rc=%hd (%s)\n", SVP(m_Msg), m_RC, SVP(m_ErrMsg[0]));
return true;
} // end of BuildErrorMessage
const char *DBX::GetErrorMessage(int i)
......@@ -910,6 +913,7 @@ ODBConn::ODBConn(PGLOBAL g, TDBODBC *tdbp)
m_Connect = NULL;
m_Updatable = true;
m_Transact = false;
m_Scrollable = (tdbp) ? tdbp->Scrollable : false;
m_IDQuoteChar[0] = '"';
m_IDQuoteChar[1] = 0;
//*m_ErrMsg = '\0';
......@@ -932,9 +936,10 @@ bool ODBConn::Check(RETCODE rc)
if (trace) {
DBX x(rc);
x.BuildErrorMessage(this, m_hstmt);
htrc("ODBC Success With Info, hstmt=%p %s\n",
m_hstmt, x.GetErrorMessage(0));
if (x.BuildErrorMessage(this, m_hstmt))
htrc("ODBC Success With Info, hstmt=%p %s\n",
m_hstmt, x.GetErrorMessage(0));
} // endif trace
// Fall through
......@@ -953,8 +958,10 @@ void ODBConn::ThrowDBX(RETCODE rc, PSZ msg, HSTMT hstmt)
{
DBX* xp = new(m_G) DBX(rc, msg);
xp->BuildErrorMessage(this, hstmt);
throw xp;
// Don't throw if no error
if (xp->BuildErrorMessage(this, hstmt))
throw xp;
} // end of ThrowDBX
void ODBConn::ThrowDBX(PSZ msg)
......@@ -1298,25 +1305,28 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols)
b = false;
if (m_hstmt) {
// All this did not seems to make sense and was been commented out
// if (IsOpen())
// Close(SQL_CLOSE);
// This is a Requery
rc = SQLFreeStmt(m_hstmt, SQL_CLOSE);
if (trace && !Check(rc))
htrc("Error: SQLFreeStmt rc=%d\n", rc);
if (!Check(rc))
ThrowDBX(rc, "SQLFreeStmt");
hstmt = m_hstmt;
m_hstmt = NULL;
ThrowDBX(MSG(SEQUENCE_ERROR));
} else {
rc = SQLAllocStmt(m_hdbc, &hstmt);
} // endif m_hstmt
rc = SQLAllocStmt(m_hdbc, &hstmt);
if (!Check(rc))
ThrowDBX(rc, "SQLAllocStmt");
if (m_Scrollable) {
rc = SQLSetStmtAttr(hstmt, SQL_ATTR_CURSOR_SCROLLABLE,
(void*)SQL_SCROLLABLE, 0);
if (!Check(rc))
ThrowDBX(SQL_INVALID_HANDLE, "SQLAllocStmt");
ThrowDBX(rc, "SQLSetStmtAttr");
} // endif hstmt
} // endif m_Scrollable
OnSetOptions(hstmt);
b = true;
......@@ -2332,6 +2342,34 @@ int ODBConn::GetCatInfo(CATPARM *cap)
return irc;
} // end of GetCatInfo
/***********************************************************************/
/* Restart from beginning of result set */
/***********************************************************************/
bool ODBConn::Rewind(char *sql, ODBCCOL *tocols)
{
RETCODE rc;
if (!m_hstmt)
return false;
if (m_Scrollable) {
try {
rc = SQLFetchScroll(m_hstmt, SQL_FETCH_ABSOLUTE, 0);
if (rc != SQL_NO_DATA_FOUND)
ThrowDBX(rc, "SQLFetchScroll", m_hstmt);
} catch(DBX *x) {
strcpy(m_G->Message, x->GetErrorMessage(0));
return true;
} // end try/catch
} else if (ExecDirectSQL(sql, tocols) < 0)
return true;
return false;
} // end of Rewind
/***********************************************************************/
/* Disconnect connection */
/***********************************************************************/
......
......@@ -95,7 +95,7 @@ class DBX : public BLOCK {
const char *GetErrorMessage(int i);
protected:
void BuildErrorMessage(ODBConn* pdb, HSTMT hstmt = SQL_NULL_HSTMT);
bool BuildErrorMessage(ODBConn* pdb, HSTMT hstmt = SQL_NULL_HSTMT);
// Attributes
RETCODE m_RC;
......@@ -124,6 +124,7 @@ class ODBConn : public BLOCK {
forceOdbcDialog = 0x0010}; // Always display ODBC connect dialog
int Open(PSZ ConnectString, DWORD Options = 0);
bool Rewind(char *sql, ODBCCOL *tocols);
void Close(void);
// Attributes
......@@ -190,4 +191,5 @@ class ODBConn : public BLOCK {
PSZ m_Connect;
bool m_Updatable;
bool m_Transact;
bool m_Scrollable;
}; // end of ODBConn class definition
......@@ -113,11 +113,17 @@ void CloseXMLFile(PGLOBAL, PFBLOCK, bool);
/***********************************************************************/
/* Routines for file IO with error reporting to g->Message */
/* Note: errno and strerror must be called before the message file */
/* is read in the case of XMSG compile. */
/***********************************************************************/
static void
global_open_error_msg(GLOBAL *g, int msgid, const char *path, const char *mode)
static void global_open_error_msg(GLOBAL *g, int msgid, const char *path,
const char *mode)
{
int len;
int len, rno= (int)errno;
char errmsg[256]= "";
strncat(errmsg, strerror(errno), 256);
switch (msgid)
{
case MSGID_CANNOT_OPEN:
......@@ -129,7 +135,7 @@ global_open_error_msg(GLOBAL *g, int msgid, const char *path, const char *mode)
case MSGID_OPEN_MODE_ERROR:
len= snprintf(g->Message, sizeof(g->Message) - 1,
MSG(OPEN_MODE_ERROR), // "Open(%s) error %d on %s"
mode, (int) errno, path);
mode, rno, path);
break;
case MSGID_OPEN_MODE_STRERROR:
......@@ -137,13 +143,13 @@ global_open_error_msg(GLOBAL *g, int msgid, const char *path, const char *mode)
strcat(strcpy(fmt, MSG(OPEN_MODE_ERROR)), ": %s");
len= snprintf(g->Message, sizeof(g->Message) - 1,
fmt, // Open(%s) error %d on %s: %s
mode, (int) errno, path, strerror(errno));
mode, rno, path, errmsg);
}break;
case MSGID_OPEN_STRERROR:
len= snprintf(g->Message, sizeof(g->Message) - 1,
MSG(OPEN_STRERROR), // "open error: %s"
strerror(errno));
errmsg);
break;
case MSGID_OPEN_ERROR_AND_STRERROR:
......@@ -151,13 +157,13 @@ global_open_error_msg(GLOBAL *g, int msgid, const char *path, const char *mode)
//OPEN_ERROR does not work, as it wants mode %d (not %s)
//MSG(OPEN_ERROR) "%s",// "Open error %d in mode %d on %s: %s"
"Open error %d in mode %s on %s: %s",
errno, mode, path, strerror(errno));
rno, mode, path, errmsg);
break;
case MSGID_OPEN_EMPTY_FILE:
len= snprintf(g->Message, sizeof(g->Message) - 1,
MSG(OPEN_EMPTY_FILE), // "Opening empty file %s: %s"
path, strerror(errno));
path, errmsg);
break;
default:
......@@ -285,12 +291,9 @@ PQRYRES PlgAllocResult(PGLOBAL g, int ncol, int maxres, int ids,
// Get header from message file
strncpy(cname, PlugReadMessage(g, ids + crp->Ncol, NULL), NAM_LEN);
cname[NAM_LEN] = 0; // for truncated long names
//#elif defined(WIN32)
// Get header from ressource file
// LoadString(s_hModule, ids + crp->Ncol, cname, sizeof(cname));
#else // !WIN32
#else // !XMSG
GetRcString(ids + crp->Ncol, cname, sizeof(cname));
#endif // !WIN32
#endif // !XMSG
crp->Name = (PSZ)PlugSubAlloc(g, NULL, strlen(cname) + 1);
strcpy(crp->Name, cname);
} else
......@@ -982,7 +985,7 @@ void PlugCleanup(PGLOBAL g, bool dofree)
/* This is the place to reset the pointer on domains. */
/*******************************************************************/
dbuserp->Subcor = false;
dbuserp->Step = STEP(PARSING_QUERY);
dbuserp->Step = "New query"; // was STEP(PARSING_QUERY);
dbuserp->ProgMax = dbuserp->ProgCur = dbuserp->ProgSav = 0;
} // endif dofree
......
......@@ -2,7 +2,7 @@
/* */
/* PROGRAM NAME: PLUGUTIL */
/* ------------- */
/* Version 2.8 */
/* Version 2.9 */
/* */
/* COPYRIGHT: */
/* ---------- */
......@@ -76,6 +76,9 @@
#include "osutil.h"
#include "global.h"
#if defined(NEWMSG)
#include "rcmsg.h"
#endif // NEWMSG
#if defined(WIN32)
extern HINSTANCE s_hModule; /* Saved module handle */
......@@ -156,7 +159,9 @@ PGLOBAL PlugInit(LPCSTR Language, uint worksize)
char errmsg[256];
sprintf(errmsg, MSG(WORK_AREA), g->Message);
strcpy(g->Message, errmsg);
} /* endif Sarea */
g->Sarea_Size = 0;
} else
g->Sarea_Size = worksize;
} /* endif g */
......@@ -231,7 +236,7 @@ BOOL PlugIsAbsolutePath(LPCSTR path)
LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath)
{
char newname[_MAX_PATH];
char direc[_MAX_DIR], defdir[_MAX_DIR];
char direc[_MAX_DIR], defdir[_MAX_DIR], tmpdir[_MAX_DIR];
char fname[_MAX_FNAME];
char ftype[_MAX_EXT];
#if !defined(UNIX) && !defined(UNIV_LINUX)
......@@ -264,7 +269,7 @@ LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath)
} // endif FileName
#endif // !WIN32
if (strcmp(prefix, ".") && !PlugIsAbsolutePath(defpath))
if (prefix && strcmp(prefix, ".") && !PlugIsAbsolutePath(defpath))
{
char tmp[_MAX_PATH];
int len= snprintf(tmp, sizeof(tmp) - 1, "%s%s%s",
......@@ -275,7 +280,19 @@ LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath)
}
_splitpath(FileName, drive, direc, fname, ftype);
_splitpath(defpath, defdrv, defdir, NULL, NULL);
if (defpath) {
char c = defpath[strlen(defpath) - 1];
strcpy(tmpdir, defpath);
if (c != '/' && c != '\\')
strcat(tmpdir, "/");
} else
strcpy(tmpdir, "./");
_splitpath(tmpdir, defdrv, defdir, NULL, NULL);
if (trace > 1) {
htrc("after _splitpath: FileName=%s\n", FileName);
......@@ -329,10 +346,12 @@ char *PlugReadMessage(PGLOBAL g, int mid, char *m)
//GetPrivateProfileString("Message", msglang, "Message\\english.msg",
// msgfile, _MAX_PATH, plgini);
strcat(strcat(strcpy(msgfile, msg_path), msglang()), ".msg");
//strcat(strcat(strcpy(msgfile, msg_path), msglang()), ".msg");
strcat(strcpy(buff, msglang()), ".msg");
PlugSetPath(msgfile, NULL, buff, msg_path);
if (!(mfile = fopen(msgfile, "rt"))) {
sprintf(stmsg, "Fail to open message file %s for %s", msgfile, msglang);
sprintf(stmsg, "Fail to open message file %s", msgfile);
goto err;
} // endif mfile
......@@ -382,7 +401,7 @@ char *PlugGetMessage(PGLOBAL g, int mid)
{
char *msg;
#if !defined(UNIX) && !defined(UNIV_LINUX)
#if 0 // was !defined(UNIX) && !defined(UNIV_LINUX)
int n = LoadString(s_hModule, (uint)mid, (LPTSTR)stmsg, 200);
if (n == 0) {
......@@ -395,10 +414,10 @@ char *PlugGetMessage(PGLOBAL g, int mid)
return msg;
} // endif n
#else // UNIX
#else // ALL
if (!GetRcString(mid, stmsg, 200))
sprintf(stmsg, "Message %d not found", mid);
#endif // UNIX
#endif // ALL
if (g) {
// Called by STEP
......
This diff is collapsed.
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by PlgSock.rc
//
#if 0
#define IDS_00 115
#define IDS_01 116
#define IDS_02 117
#define IDS_03 118
#define IDS_04 119
#define IDS_05 120
#define IDS_06 121
#define IDS_07 122
#define IDS_08 123
#define IDS_09 124
#define IDS_10 125
#define IDS_11 126
#define IDS_12 127
#define IDS_13 128
#define IDS_14 129
#define IDS_15 130
#define IDS_16 131
#define IDS_17 132
#define IDS_18 133
#define IDS_19 134
#define IDS_20 135
#define IDS_21 136
#endif // 0
#define IDS_TABLES 143
#define IDS_TAB_01 144
#define IDS_TAB_02 145
#define IDS_TAB_03 146
#define IDS_TAB_04 147
#define IDS_TAB_05 148
#define IDS_COLUMNS 159
#define IDS_COL_01 160
#define IDS_COL_02 161
#define IDS_COL_03 162
#define IDS_COL_04 163
#define IDS_COL_05 164
#define IDS_COL_06 165
#define IDS_COL_07 166
#define IDS_COL_08 167
#define IDS_COL_09 168
#define IDS_COL_10 169
#define IDS_COL_11 170
#define IDS_COL_12 171
#if 0
#define IDS_INFO 175
#define IDS_INF_01 176
#define IDS_INF_02 177
#define IDS_INF_03 178
#define IDS_INF_04 179
#define IDS_INF_05 180
#define IDS_INF_06 181
#define IDS_INF_07 182
#define IDS_INF_08 183
#define IDS_INF_09 184
#define IDS_INF_10 185
#define IDS_INF_11 186
#define IDS_INF_12 187
#define IDS_INF_13 188
#define IDS_INF_14 189
#define IDS_INF_15 190
#endif // 0
#define IDS_PKEY 191
#define IDS_PKY_01 192
#define IDS_PKY_02 193
#define IDS_PKY_03 194
#define IDS_PKY_04 195
#define IDS_PKY_05 196
#define IDS_PKY_06 197
#if 0
#define IDS_FKEY 207
#define IDS_FKY_01 208
#define IDS_FKY_02 209
#define IDS_FKY_03 210
#define IDS_FKY_04 211
#define IDS_FKY_05 212
#define IDS_FKY_06 213
#define IDS_FKY_07 214
#define IDS_FKY_08 215
#define IDS_FKY_09 216
#define IDS_FKY_10 217
#define IDS_FKY_11 218
#define IDS_FKY_12 219
#define IDS_FKY_13 220
#endif // 0
#define IDS_STAT 223
#define IDS_STA_01 224
#define IDS_STA_02 225
#define IDS_STA_03 226
#define IDS_STA_04 227
#define IDS_STA_05 228
#define IDS_STA_06 229
#define IDS_STA_07 230
#define IDS_STA_08 231
#define IDS_STA_09 232
#define IDS_STA_10 233
#define IDS_STA_11 234
#define IDS_STA_12 235
#define IDS_STA_13 236
#if 0
#define IDS_SPCOLS 1247
#define IDS_SPC_01 1248
#define IDS_SPC_02 1249
#define IDS_SPC_03 1250
#define IDS_SPC_04 1251
#define IDS_SPC_05 1252
#define IDS_SPC_06 1253
#define IDS_SPC_07 1254
#define IDS_SPC_08 1255
#define IDS_CNX 1263
#define IDS_CNX_01 1264
#define IDS_CNX_02 1265
#define IDS_CNX_03 1266
#define IDS_CNX_04 1267
#define IDS_PLGCOL 1279
#define IDS_PLG_01 1280
#define IDS_PLG_02 1281
#define IDS_PLG_03 1282
#define IDS_PLG_04 1283
#define IDS_PLG_05 1284
#define IDS_PLG_06 1285
#define IDS_PLG_07 1286
#define IDS_PLG_08 1287
#define IDS_PLG_09 1288
#endif // 0
#define IDS_DRIVER 1290
#define IDS_DRV_01 1291
#define IDS_DRV_02 1292
#define IDS_DSRC 1295
#define IDS_DSC_01 1296
#define IDS_DSC_02 1297
//#define IDS_DSC_03 1298
//#define IDS_DSC_04 1299
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 1300
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1440
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
#define IDS_TABLES 100
#define IDS_TAB_01 101
#define IDS_TAB_02 102
#define IDS_TAB_03 103
#define IDS_TAB_04 104
#define IDS_TAB_05 105
#define IDS_COLUMNS 106
#define IDS_COL_01 107
#define IDS_COL_02 108
#define IDS_COL_03 109
#define IDS_COL_04 110
#define IDS_COL_05 111
#define IDS_COL_06 112
#define IDS_COL_07 113
#define IDS_COL_08 114
#define IDS_COL_09 115
#define IDS_COL_10 116
#define IDS_COL_11 117
#define IDS_COL_12 118
#define IDS_PKEY 119
#define IDS_PKY_01 120
#define IDS_PKY_02 121
#define IDS_PKY_03 122
#define IDS_PKY_04 123
#define IDS_PKY_05 124
#define IDS_PKY_06 125
#define IDS_STAT 126
#define IDS_STA_01 127
#define IDS_STA_02 128
#define IDS_STA_03 129
#define IDS_STA_04 130
#define IDS_STA_05 131
#define IDS_STA_06 132
#define IDS_STA_07 133
#define IDS_STA_08 134
#define IDS_STA_09 135
#define IDS_STA_10 136
#define IDS_STA_11 137
#define IDS_STA_12 138
#define IDS_STA_13 139
#define IDS_DRIVER 140
#define IDS_DRV_01 141
#define IDS_DRV_02 142
#define IDS_DSRC 143
#define IDS_DSC_01 144
#define IDS_DSC_02 145
......@@ -161,7 +161,7 @@ class TDBFMT : public TDBCSV {
protected:
virtual bool PrepareWriting(PGLOBAL g)
{strcpy(g->Message, "FMT is read only"); return true;}
{sprintf(g->Message, MSG(TABLE_READ_ONLY), "FMT"); return true;}
// Members
PSZ *FldFormat; // Field read format
......
......@@ -859,6 +859,7 @@ bool TDBMYSQL::OpenDB(PGLOBAL g)
/* Table already open, just replace it at its beginning. */
/*******************************************************************/
Myc.Rewind();
N = -1;
return false;
} // endif use
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment