int main()

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;

}