+ if (SQLExecDirect(hstmt, (UCHAR FAR *) sqlStmt.c_str(), SQL_NTS) != SQL_SUCCESS)
+ {
+ // Check for "Base table not found" error and ignore
+ pDb->GetNextError(henv, hdbc, hstmt);
+ if (wxStrcmp(pDb->sqlState,"S0002") && wxStrcmp(pDb->sqlState, "S1000")) // "Base table not found"
+ {
+ // Check for product specific error codes
+ if (!((pDb->Dbms() == dbmsSYBASE_ASA && !wxStrcmp(pDb->sqlState,"42000")) || // 5.x (and lower?)
+ (pDb->Dbms() == dbmsSYBASE_ASE && !wxStrcmp(pDb->sqlState,"37000")) ||
+ (pDb->Dbms() == dbmsPOSTGRES && !wxStrcmp(pDb->sqlState,"08S01"))))
+ {
+ pDb->DispNextError();
+ pDb->DispAllErrors(henv, hdbc, hstmt);
+ pDb->RollbackTrans();
+ CloseCursor(hstmt);
+ return(FALSE);
+ }
+ }
+ }
+
+ // Commit the transaction and close the cursor
+ if (! pDb->CommitTrans())
+ return(FALSE);
+ if (! CloseCursor(hstmt))
+ return(FALSE);
+
+ return(TRUE);
+} // wxDbTable::DropTable()
+
+
+/********** wxDbTable::CreateIndex() **********/
+bool wxDbTable::CreateIndex(const char * idxName, bool unique, int noIdxCols, wxDbIdxDef *pIdxDefs, bool attemptDrop)
+{
+ wxString sqlStmt;
+
+ // Drop the index first
+ if (attemptDrop && !DropIndex(idxName))
+ return (FALSE);
+
+ // MySQL (and possibly Sybase ASE?? - gt) require that any columns which are used as portions
+ // of an index have the columns defined as "NOT NULL". During initial table creation though,
+ // it may not be known which columns are necessarily going to be part of an index (e.g. the
+ // table was created, then months later you determine that an additional index while
+ // give better performance, so you want to add an index).
+ //
+ // The following block of code will modify the column definition to make the column be
+ // defined with the "NOT NULL" qualifier.
+ if (pDb->Dbms() == dbmsMY_SQL)
+ {
+ wxString sqlStmt;
+ int i;
+ bool ok = TRUE;
+ for (i = 0; i < noIdxCols && ok; i++)
+ {
+ int j = 0;
+ bool found = FALSE;
+ // Find the column definition that has the ColName that matches the
+ // index column name. We need to do this to get the DB_DATA_TYPE of
+ // the index column, as MySQL's syntax for the ALTER column requires
+ // this information
+ while (!found && (j < this->noCols))
+ {
+ if (wxStrcmp(colDefs[j].ColName,pIdxDefs[i].ColName) == 0)
+ found = TRUE;
+ if (!found)
+ j++;
+ }
+
+ if (found)
+ {
+ wxString typeNameAndSize;
+
+ switch(colDefs[j].DbDataType)
+ {
+ case DB_DATA_TYPE_VARCHAR:
+ typeNameAndSize = pDb->GetTypeInfVarchar().TypeName;
+ break;
+ case DB_DATA_TYPE_INTEGER:
+ typeNameAndSize = pDb->GetTypeInfInteger().TypeName;
+ break;
+ case DB_DATA_TYPE_FLOAT:
+ typeNameAndSize = pDb->GetTypeInfFloat().TypeName;
+ break;
+ case DB_DATA_TYPE_DATE:
+ typeNameAndSize = pDb->GetTypeInfDate().TypeName;
+ break;
+ }
+
+ // For varchars, append the size of the string
+ if (colDefs[j].DbDataType == DB_DATA_TYPE_VARCHAR)
+ {
+ wxString s;
+ s.sprintf("(%d)", colDefs[i].SzDataObj);
+ typeNameAndSize += s.c_str();
+ }
+
+ sqlStmt.sprintf("ALTER TABLE %s MODIFY %s %s NOT NULL",tableName,pIdxDefs[i].ColName,typeNameAndSize.c_str());
+ ok = pDb->ExecSql(sqlStmt.c_str());
+
+ if (!ok)
+ {
+ wxODBC_ERRORS retcode;
+ // Oracle returns a DB_ERR_GENERAL_ERROR if the column is already
+ // defined to be NOT NULL, but reportedly MySQL doesn't mind.
+ // This line is just here for debug checking of the value
+ retcode = (wxODBC_ERRORS)pDb->DB_STATUS;
+ }
+ }
+ else
+ ok = FALSE;
+ }
+ if (ok)
+ pDb->CommitTrans();
+ else
+ {
+ pDb->RollbackTrans();
+ return(FALSE);
+ }
+ }
+
+ // Build a CREATE INDEX statement
+ sqlStmt = "CREATE ";
+ if (unique)
+ sqlStmt += "UNIQUE ";
+
+ sqlStmt += "INDEX ";
+ sqlStmt += idxName;
+ sqlStmt += " ON ";
+ sqlStmt += tableName;
+ sqlStmt += " (";
+
+ // Append list of columns making up index
+ int i;
+ for (i = 0; i < noIdxCols; i++)
+ {
+ sqlStmt += pIdxDefs[i].ColName;
+ /* Postgres doesn't cope with ASC */
+ if (pDb->Dbms() != dbmsPOSTGRES)
+ {
+ if (pIdxDefs[i].Ascending)
+ sqlStmt += " ASC";
+ else
+ sqlStmt += " DESC";
+ }
+
+ if ((i + 1) < noIdxCols)
+ sqlStmt += ",";
+ }
+
+ // Append closing parentheses
+ sqlStmt += ")";
+
+ pDb->WriteSqlLog(sqlStmt.c_str());
+
+#ifdef DBDEBUG_CONSOLE
+ cout << endl << sqlStmt.c_str() << endl << endl;