/* odbc-test-08.c: SQLPrepare and SQLExecute instead of SQLExecDirect
 * This program compiled and run, without changes, on:
 *   Red Hat Linux 8.0, gcc 3.2, unixODBC 2.2.2
 *     ("gcc -Wall odbc-test-08.c -o odbc-test-08 -lodbc")
 *   Windows 2000 Professional, Microsoft Visual C++ 6.0
 *   Windows 2000 Professional, Borland C++ Builder 5.0
 * All of those with Mimer 9.1.3, and Mimer ODBC driver 9.something
 * Thomas Padron-McCarthy (Thomas.Padron-McCarthy@tech.oru.se)
 * October 7, 2003
 */

#include <stdlib.h>
#include <stdio.h>
#if defined(_MSDOS) || defined(_WIN32)
#include <windows.h>
#endif
#include "sqlext.h"

int main(void) {
  SQLHENV eh;
  SQLHDBC ch;
  SQLHSTMT sh1;
  SQLHSTMT sh2;
  SQLINTEGER number;
  SQLCHAR name[20 + 1];
  SQLINTEGER number_size, name_size;

  /* ODBC 2.x uses SQLAllocEnv, SQLAllocConnect and SQLAllocStmt.
   * ODBC 3.x uses SQLAllocHandle, with different arguments, for all of those.
   * First: Allocate environment handle.
   */
  if (SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &eh) != SQL_SUCCESS) {
    fprintf(stderr, "Kunde inte allokera en ODBC-omgivning.\n");
    return EXIT_FAILURE;
  }

  /* Set the ODBC version attribute,
   * so ODBC knows which ODBC version this application was written for.
   */
  if (SQLSetEnvAttr(eh,
		    SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3,
		    SQL_IS_INTEGER) != SQL_SUCCESS) {
    fprintf(stderr, "Failed to set ODBC version to SQL_OV_ODBC3.\n");
    return EXIT_FAILURE;
  }

  /* Allocate connection handle */
  if (SQLAllocHandle(SQL_HANDLE_DBC, eh, &ch) != SQL_SUCCESS) {
    fprintf(stderr, "Kunde inte allokera ett anslutningsobjekt.\n");
    return EXIT_FAILURE;
  }

  if (SQLConnect(ch, (SQLCHAR*)"demobasen", SQL_NTS,
		 (SQLCHAR*)"demouser", SQL_NTS,
		 (SQLCHAR*)"fnord", SQL_NTS) != SQL_SUCCESS) {
    fprintf(stderr, "Kunde inte ansluta till datakällan 'demobasen'.\n");
    return EXIT_FAILURE;
  }

  /* Allocate statement handles */
  if (SQLAllocHandle(SQL_HANDLE_STMT, ch, &sh1) != SQL_SUCCESS) {
    fprintf(stderr, "Kunde inte allokera statement handle sh1.\n");
    return EXIT_FAILURE;
  }
  if (SQLAllocHandle(SQL_HANDLE_STMT, ch, &sh2) != SQL_SUCCESS) {
    fprintf(stderr, "Kunde inte allokera statement handle sh1.\n");
    return EXIT_FAILURE;
  }

  if (SQLPrepare(sh1, (SQLCHAR*)"select Nummer, Namn from Person", SQL_NTS)
      != SQL_SUCCESS) {
    fprintf(stderr, "SQLPrepare misslyckades.\n");
    return EXIT_FAILURE;
  }

  if (SQLExecute(sh1) != SQL_SUCCESS) {
    fprintf(stderr, "Kunde inte köra SELECT-frågan.\n");
    return EXIT_FAILURE;
  }

  SQLBindCol(sh1, 1, SQL_C_SLONG, &number, sizeof number, &number_size);
  SQLBindCol(sh1, 2, SQL_C_CHAR, name, sizeof name, &name_size);

  SQLBindParameter(sh2, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER,
		   1, 0, &number, sizeof number, &number_size);
  SQLBindParameter(sh2, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,
		   50, 0, name, sizeof name, &name_size);

  if (SQLPrepare(sh2,
		 (SQLCHAR*)"INSERT INTO Hamster (Nummer, Namn) values (?, ?)",
		 SQL_NTS) != SQL_SUCCESS) {
    fprintf(stderr, "SQLPrepare misslyckades.\n");
    return EXIT_FAILURE;
  }

  while (SQLFetch(sh1) == SQL_SUCCESS) {
    printf("Nummer %d, med namnet %s\n", (int)number, name);
    if (SQLExecute(sh2) != SQL_SUCCESS) {
      fprintf(stderr, "INSERT INTO misslyckades.\n");
      return EXIT_FAILURE;
    }
    printf("  - inlagd i Hamster-tabellen.\n");
  } /* while */

  SQLFreeHandle(SQL_HANDLE_STMT, sh1);
  SQLFreeHandle(SQL_HANDLE_STMT, sh2);
  SQLDisconnect(ch);
  SQLFreeHandle(SQL_HANDLE_DBC, ch);
  SQLFreeHandle(SQL_HANDLE_ENV, eh);

  return EXIT_SUCCESS;
} /* main */

