Skip to content

Commit

Permalink
Data transfer improved
Browse files Browse the repository at this point in the history
  • Loading branch information
dmtolpeko committed Dec 28, 2017
1 parent 069c7ee commit 795c1a0
Show file tree
Hide file tree
Showing 16 changed files with 468 additions and 92 deletions.
34 changes: 31 additions & 3 deletions sqldata/sqlasaapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ SqlAsaApi::SqlAsaApi()

_native_error = 0;
_native_error_text[0] = '\x0';

_char_as_wchar = false;
}

SqlAsaApi::~SqlAsaApi()
Expand Down Expand Up @@ -100,6 +102,9 @@ int SqlAsaApi::Connect(size_t *time_spent)
return -1;
}

// Initialize session
InitSession();

// Set session attributes
rc = SetSession();

Expand Down Expand Up @@ -266,7 +271,13 @@ int SqlAsaApi::OpenCursor(const char *query, size_t buffer_rows, int buffer_memo

_cursor_cols[i]._native_dt = native_dt;
_cursor_cols[i]._len = column_size;


// All char data is set to be extracted as wide char (UTF-16/UCS-2)
if((native_dt == SQL_CHAR || native_dt == SQL_VARCHAR) && !catalog_query && _char_as_wchar)
{
_cursor_cols[i]._native_dt = (native_dt == SQL_CHAR) ? SQL_WCHAR : SQL_WVARCHAR;
}
else
// For DECIMAL/NUMERIC column size includes precision only
if(native_dt == SQL_DECIMAL || native_dt == SQL_NUMERIC)
{
Expand Down Expand Up @@ -563,7 +574,7 @@ int SqlAsaApi::OpenCursor(const char *query, size_t buffer_rows, int buffer_memo
*allocated_array_rows = _cursor_allocated_rows;

if(rows_fetched != NULL)
*rows_fetched = _cursor_fetched;
*rows_fetched = (int)_cursor_fetched;

if(cols != NULL)
*cols = _cursor_cols;
Expand Down Expand Up @@ -605,7 +616,7 @@ int SqlAsaApi::Fetch(int *rows_fetched, size_t *time_spent)
}

if(rows_fetched != NULL)
*rows_fetched = _cursor_fetched;
*rows_fetched = (int)_cursor_fetched;

if(time_spent != NULL)
*time_spent = GetTickCount() - start;
Expand Down Expand Up @@ -905,6 +916,10 @@ int SqlAsaApi::ReadSchema(const char *select, const char *exclude, bool read_cns

ReadReservedWords();

// Reset initialization error text so it will not be later associated with the data transfer
*_native_error_text = '\x0';
_error = 0;

return rc;
}

Expand Down Expand Up @@ -2249,6 +2264,19 @@ int SqlAsaApi::ReadReservedWords()
return 0;
}

// Initialize session
int SqlAsaApi::InitSession()
{
if(_parameters == NULL)
return -1;

SqlApiBase::InitSession();

if(_parameters->GetTrue("-sybase_asa_char_as_wchar") != NULL)
_char_as_wchar = true;

return 0;
}
// Set session attributes
int SqlAsaApi::SetSession()
{
Expand Down
6 changes: 5 additions & 1 deletion sqldata/sqlasaapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ class SqlAsaApi : public SqlApiBase
std::string _dsn;

// Attribute to store last number of fetched rows (SQL_ATTR_ROWS_FETCHED_PTR)
int _cursor_fetched;
SQLULEN _cursor_fetched;

// Extract all character data as 2-byte Unicode (UTF-16/UCS-2)
bool _char_as_wchar;

public:
SqlAsaApi();
Expand Down Expand Up @@ -127,6 +130,7 @@ class SqlAsaApi : public SqlApiBase
bool IsQuoteRequired(const char *name);

private:
int InitSession();
// Set session attributes
int SetSession();
// Set version of the connected database
Expand Down
62 changes: 31 additions & 31 deletions sqldata/sqlctapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ SqlCtApi::SqlCtApi()
_cs_loc_alloc = NULL;
_cs_locale = NULL;
_ct_bind = NULL;
_ct_cancel = NULL;
_ct_command = NULL;
_ct_con_alloc = NULL;
_ct_con_drop = NULL;
Expand Down Expand Up @@ -164,6 +165,7 @@ int SqlCtApi::Init()
_cs_locale = (cs_localeFunc)Os::GetProcAddress(_cs_dll, "cs_locale");

_ct_bind = (ct_bindFunc)Os::GetProcAddress(_ct_dll, "ct_bind");
_ct_cancel = (ct_cancelFunc)Os::GetProcAddress(_ct_dll, "ct_cancel");
_ct_command = (ct_commandFunc)Os::GetProcAddress(_ct_dll, "ct_command");
_ct_con_alloc = (ct_con_allocFunc)Os::GetProcAddress(_ct_dll, "ct_con_alloc");
_ct_con_drop = (ct_con_dropFunc)Os::GetProcAddress(_ct_dll, "ct_con_drop");
Expand All @@ -182,7 +184,7 @@ int SqlCtApi::Init()
_ct_send = (ct_sendFunc)Os::GetProcAddress(_ct_dll, "ct_send");

if(_cs_ctx_alloc == NULL || _cs_config == NULL || _cs_ctx_drop == NULL || _cs_dt_info == NULL || _cs_locale == NULL ||
_cs_loc_alloc == NULL || _ct_bind == NULL || _ct_command == NULL ||
_cs_loc_alloc == NULL || _ct_bind == NULL || _ct_cancel == NULL || _ct_command == NULL ||
_ct_con_alloc == NULL || _ct_con_drop == NULL || _ct_con_props == NULL || _ct_connect == NULL ||
_ct_close == NULL || _ct_cmd_alloc == NULL || _ct_cmd_drop == NULL || _ct_describe == NULL ||
_ct_diag == NULL || _ct_exit == NULL || _ct_fetch == NULL || _ct_init == NULL ||
Expand Down Expand Up @@ -472,6 +474,10 @@ int SqlCtApi::OpenCursor(const char *query, size_t buffer_rows, int buffer_memor

size_t start = Os::GetTickCount();

// Reset the previous errors
_ct_diag(_connection, CS_CLEAR, CS_CLIENTMSG_TYPE, CS_UNUSED, NULL);
_ct_diag(_connection, CS_CLEAR, CS_SERVERMSG_TYPE, CS_UNUSED, NULL);

// Allocate command
int rc = _ct_cmd_alloc(_connection, &_cursor_cmd);

Expand All @@ -492,11 +498,15 @@ int SqlCtApi::OpenCursor(const char *query, size_t buffer_rows, int buffer_memor
}

// Process the result set (execute ct_result only once)
// Even if SELECT is incorrect (syntax errors i.e.) ct_command, ct_send and ct_results return CS_SUCCEED, but
// ct_results returns CS_CMD_FAIL (4048) in type (second param)
if((rc = _ct_results(_cursor_cmd, &type)) != CS_SUCCEED || type != CS_ROW_RESULT)
{
SetError();
_ct_cmd_drop(_cursor_cmd);

// We must cancel of fetch all ct_results before dropping the command; otherwise this drop fails and all subsequent statements will fail as well
rc = _ct_cancel(NULL, _cursor_cmd, CS_CANCEL_ALL);
rc = _ct_cmd_drop(_cursor_cmd);
return -1;
}

Expand Down Expand Up @@ -740,7 +750,20 @@ int SqlCtApi::OpenCursor(const char *query, size_t buffer_rows, int buffer_memor
{
_cursor_cols[i]._native_fetch_dt = CS_CHAR_TYPE;

// All date/time data type are fetched in full length, since ANSI ISO format cannot be specified separately for each type
// All date/time data types are fetched in full length, since ANSI ISO format cannot be specified separately for each type
_cursor_cols[i]._fetch_len = 26;
_cursor_cols[i]._data = new char[_cursor_cols[i]._fetch_len * _cursor_allocated_rows];

fmt[i].datatype = CS_CHAR_TYPE;
fmt[i].maxlength = (CS_INT)_cursor_cols[i]._fetch_len;
}
else
// TIME, length is 4
if(_cursor_cols[i]._native_dt == CS_TIME_TYPE)
{
_cursor_cols[i]._native_fetch_dt = CS_CHAR_TYPE;

// All date/time data types are fetched in full length, since ANSI ISO format cannot be specified separately for each type
_cursor_cols[i]._fetch_len = 26;
_cursor_cols[i]._data = new char[_cursor_cols[i]._fetch_len * _cursor_allocated_rows];

Expand Down Expand Up @@ -884,31 +907,8 @@ int SqlCtApi::Fetch(int *rows_fetched, size_t *time_spent)
// Close the cursor and deallocate buffers
int SqlCtApi::CloseCursor()
{
CS_INT type;
int rc = 0;

int fetched = 0;

// We must call ct_fetch until it returns NO DATA
if(_cursor_last_fetch_rc == CS_SUCCEED)
rc = _ct_fetch(_cursor_cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, (CS_INT*)&fetched);

bool more = true;

// Consume all results
while(more)
{
rc = _ct_results(_cursor_cmd, &type);

if(rc == CS_FAIL)
SetError();

if(rc != CS_SUCCEED)
{
more = false;
break;
}
}
// Close cursor can be called when not all rows are fetched (error creating table in the target database i.e.), so we need to cancel command
int rc = _ct_cancel(NULL, _cursor_cmd, CS_CANCEL_ALL);

rc = _ct_cmd_drop(_cursor_cmd);

Expand Down Expand Up @@ -1178,7 +1178,7 @@ int SqlCtApi::ReadTableColumns(std::string &condition)

len = GetLen(&cols[2], i);

// Column
// Column (without [] even if the name contains blanks)
if(len != -1)
{
col_meta.column = new char[(size_t)len + 1];
Expand Down Expand Up @@ -1739,7 +1739,7 @@ void SqlCtApi::FindSybasePaths(std::list<std::string> &paths)
void SqlCtApi::SetError()
{
CS_CLIENTMSG msg;
CS_CLIENTMSG smsg;
CS_SERVERMSG smsg;

// Try to get client message (returned by ct_connect i.e.)
CS_RETCODE rc = _ct_diag(_connection, CS_GET, CS_CLIENTMSG_TYPE, 1, &msg);
Expand All @@ -1750,7 +1750,7 @@ void SqlCtApi::SetError()
rc = _ct_diag(_connection, CS_GET, CS_SERVERMSG_TYPE, 1, &smsg);

if(rc == CS_SUCCEED)
strcpy(_native_error_text, smsg.msgstring);
strcpy(_native_error_text, smsg.text);
}
else
strcpy(_native_error_text, msg.msgstring);
Expand Down
2 changes: 2 additions & 0 deletions sqldata/sqlctapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ typedef CS_RETCODE (CS_PUBLIC *cs_dt_infoFunc)( CS_CONTEXT *context, CS_INT acti
typedef CS_RETCODE (CS_PUBLIC *cs_loc_allocFunc)(CS_CONTEXT *context, CS_LOCALE **loc_pointer);
typedef CS_RETCODE (CS_PUBLIC *cs_localeFunc)(CS_CONTEXT *context, CS_INT action, CS_LOCALE *locale, CS_INT type, CS_CHAR *buffer, CS_INT buflen, CS_INT *outlen);
typedef CS_RETCODE (CS_PUBLIC *ct_bindFunc)(CS_COMMAND *cmd, CS_INT item, CS_DATAFMT *datafmt, CS_VOID *buf, CS_INT *outputlen, CS_SMALLINT *indicator);
typedef CS_RETCODE (CS_PUBLIC *ct_cancelFunc)(CS_CONNECTION *connection, CS_COMMAND *cmd, CS_INT type);
typedef CS_RETCODE (CS_PUBLIC *ct_commandFunc)(CS_COMMAND *cmd, CS_INT type, CS_CHAR *buf, CS_INT buflen, CS_INT option);
typedef CS_RETCODE (CS_PUBLIC *ct_con_allocFunc)(CS_CONTEXT *context, CS_CONNECTION **connection);
typedef CS_RETCODE (CS_PUBLIC *ct_con_dropFunc)(CS_CONNECTION *connection);
Expand Down Expand Up @@ -106,6 +107,7 @@ class SqlCtApi : public SqlApiBase
cs_loc_allocFunc _cs_loc_alloc;
cs_localeFunc _cs_locale;
ct_bindFunc _ct_bind;
ct_cancelFunc _ct_cancel;
ct_commandFunc _ct_command;
ct_con_allocFunc _ct_con_alloc;
ct_con_dropFunc _ct_con_drop;
Expand Down
Loading

0 comments on commit 795c1a0

Please sign in to comment.