in src/odbc/rsodbc/rsodbcsql/rsodbcsql.c [35:351]
int main(int argc, char **argv)
{
HENV lpEnv = NULL;
HDBC lpDbc = NULL;
HSTMT lpStmt = NULL;
char *pszConnStr;
long long llStartTime;
long long llEndTime;
if(argc == 1)
{
// Usage
printf("Usage: rsodbcsql \"DSN=<dsn name>\" | \"DRIVER={driver name};HOST=host_name;PORT=port_number;UID=user_name;Database=db_name[;PWD=password]\" [file.sql|query] \n");
printf("\n");
printf("DRIVER - Name of the driver: Amazon Redshift ODBC Driver (x64)'. Enter name without quotes.\n");
printf("DSN - Name for the connection. \n");
printf("HOST - Host name or IP address for the Redshift server. \n");
printf("PORT - TCP/IP port number for the connection. Recommended port is the default port: 5439. \n");
printf("UID - User name to use when connecting to the database. \n");
printf("Database - Name of the database for the connection. \n");
printf("PWD - Password to use when connecting to the database. \n");
exit(1);
}
// Allocate an environment
if (SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&lpEnv) == SQL_ERROR)
{
fprintf(stderr,"Unable to allocate an environment handle\n");
exit(-1);
}
CHECK_ODBC_RC(lpEnv,
SQL_HANDLE_ENV,
SQLSetEnvAttr(lpEnv,
SQL_ATTR_ODBC_VERSION,
(SQLPOINTER)SQL_OV_ODBC3,
0));
// Allocate a connection
CHECK_ODBC_RC(lpEnv,
SQL_HANDLE_ENV,
SQLAllocHandle(SQL_HANDLE_DBC,lpEnv,&lpDbc));
szInput[0] = '\0';
// Process argument
if (argc > 1)
{
// Connection string
pszConnStr = *++argv;
}
else
{
pszConnStr = NULL;
}
{
char *pqueryArg = (argc > 2) ? *++argv : NULL;
// char *pqueryArg = *++argv;
// if(strstr(pqueryArg,".sql") || strstr(pqueryArg,".SQL"))
// {
// gFileMode = true;
// // Query file name
// char *file_name = pqueryArg; // *++argv;
// fp = fopen(file_name,"rt");
// if (!fp) {
// printf("Not open: %s\n", file_name);
// exit(1);
// }
// printf("Open: %s\n", file_name);
// fflush(stdout);
// }
// else
// {
// // Directly treat as query
// strncpy(szInput, pqueryArg,sizeof(szInput));
// fp = NULL;
// giCmdLineOptionQuery = TRUE;
// }
auto openFile = [&]() {
if (pqueryArg && (strstr(pqueryArg, ".sql") || strstr(pqueryArg, ".SQL"))) {
gFileMode = true;
// Query file name
char *file_name = pqueryArg; // *++argv;
fp = fopen(file_name, "rt");
if (!fp) {
printf("Not open: %s\n", file_name);
exit(1);
}
if (!gQuietFileMode())
printf("Open: %s\n", file_name);
fflush(stdout);
} else {
// Directly treat as query
strncpy(szInput, pqueryArg, sizeof(szInput));
fp = NULL;
giCmdLineOptionQuery = TRUE;
}
};
if (argc > 3) {
std::string pDebugMode = std::string(*++argv);
std::transform(pDebugMode.begin(), pDebugMode.end(), pDebugMode.begin(),
[](unsigned char c) { return std::tolower(c); });
gQuietMode = pDebugMode == "quiet" ? true : false;
}
openFile();
}
if(argc > 4)
{
char *pDispDataArg = *++argv;
giDisplayData = atoi(pDispDataArg);
}
if(argc > 5)
{
char *pDispDataArg = *++argv;
giDisplayData = atoi(pDispDataArg);
}
if(argc > 6)
{
char *pBenchmarkArg = *++argv;
giBenchMarkMode = atoi(pBenchmarkArg);
}
// Connect to the driver. Use the connection string if supplied
// on the input, otherwise let the driver manager prompt for input.
CHECK_ODBC_RC(lpDbc,
SQL_HANDLE_DBC,
SQLDriverConnect(lpDbc,
GetDesktopWindow(),
(SQLCHAR *)pszConnStr,
SQL_NTS,
NULL,
0,
NULL,
SQL_DRIVER_NOPROMPT)); // SQL_DRIVER_COMPLETE
if(!gQuietFileMode()) fprintf(stderr,"Connected.\n");
/* CHECK_ODBC_RC(lpDbc,
SQL_HANDLE_DBC,
SQLSetConnectOption(lpDbc,SQL_AUTOCOMMIT,SQL_FALSE)); */
CHECK_ODBC_RC(lpDbc,
SQL_HANDLE_DBC,
SQLAllocHandle(SQL_HANDLE_STMT,lpDbc,&lpStmt));
if(!gQuietFileMode()) printf("Enter SQL commands, type quit to exit\nrsodbcsql>");
// Loop to get input and execute queries
while(ReadCmd(fp,szInput,SQL_QUERY_SIZE-1))
{
RETCODE RetCode;
SQLSMALLINT sNumResults;
size_t len = strlen(szInput);
SQLUINTEGER uiRowCount = 0;
if(len > 0 && szInput[len - 1] == '\n')
szInput[len - 1] = '\0';
// Execute the query
if (!(*szInput))
{
if(!gQuietFileMode()) printf("rsodbcsql>");
continue;
}
else
if(_stricmp(szInput,"QUIT") == 0 || _stricmp(szInput,"QUIT;") == 0)
break;
llStartTime = currentTimeMillis();
RetCode = SQLExecDirect(lpStmt,(SQLCHAR *)szInput,SQL_NTS);
switch(RetCode)
{
case SQL_SUCCESS_WITH_INFO:
{
HandleError(lpStmt,SQL_HANDLE_STMT,RetCode);
// fall through SQL_SUCCESS
}
// no break
case SQL_SUCCESS:
{
do
{
uiRowCount = 0;
// If this is a row-returning query, display
// results
CHECK_ODBC_RC(lpStmt,
SQL_HANDLE_STMT,
SQLNumResultCols(lpStmt,&sNumResults));
if (sNumResults > 0)
{
DisplayResults(lpStmt,sNumResults,&uiRowCount);
}
else
{
SQLLEN siRowCount;
CHECK_ODBC_RC(lpStmt,
SQL_HANDLE_STMT,
SQLRowCount(lpStmt,&siRowCount));
if (siRowCount >= 0)
{
if (!gQuietFileMode())
printf("%ld %s affected\n",
siRowCount,
siRowCount == 1
? "row"
: "rows");
}
}
// Check for more results
RetCode = SQLMoreResults(lpStmt);
if(RetCode == SQL_NO_DATA)
break;
else
if(RetCode == SQL_SUCCESS)
{
CHECK_ODBC_RC(lpStmt,
SQL_HANDLE_STMT,
SQLFreeStmt(lpStmt,SQL_UNBIND));
if (!gQuietFileMode()) printf("\n\n");
continue;
}
else
if(RetCode == SQL_ERROR)
{
HandleError(lpStmt,SQL_HANDLE_STMT,RetCode);
break;
}
else
break;
}while(TRUE);
break;
}
case SQL_ERROR:
{
HandleError(lpStmt,SQL_HANDLE_STMT,RetCode);
break;
}
default: fprintf(stderr,"Unexpected return code %d!\n",RetCode); break;
} // Switch
llEndTime = currentTimeMillis();
if (!gQuietFileMode()) printf("\n Total time taken for execute and fetch = %lld (milli seconds)\n", (llEndTime - llStartTime));
if(giBenchMarkMode)
printf("%u rows fetched from %hd columns.\n", (unsigned int)uiRowCount, sNumResults);
CHECK_ODBC_RC(lpStmt,
SQL_HANDLE_STMT,
SQLFreeStmt(lpStmt,SQL_CLOSE));
CHECK_ODBC_RC(lpStmt,
SQL_HANDLE_STMT,
SQLFreeStmt(lpStmt,SQL_UNBIND));
if (!gQuietFileMode()) printf("rsodbcsql>");
if(giCmdLineOptionQuery)
break;
} // Loop
error:
if(fp && fp != stdin)
{
fclose(fp);
fp = NULL;
}
// Free ODBC handles and exit
if (lpDbc)
{
SQLDisconnect(lpDbc);
SQLFreeConnect(lpDbc);
}
if (lpEnv)
SQLFreeEnv(lpEnv);
if (!gQuietFileMode()) printf("\nDisconnected.\n");
return 0;
}