#include "search_star.h" #include #include static long sMatchingSystemID [50]; static char sMatchingSystemName [50][51]; static int sNumMatchingSystems = 0; static bool SearchName (HSTMT hstmt, const char *name) { char buffer[512]; RETCODE retcode; sprintf (buffer, "SELECT OwnerID, Name FROM ProperNames " "WHERE Name LIKE '%%%s%%'", name); retcode = SQLExecDirect (hstmt, (unsigned char *) buffer, SQL_NTS); if (retcode == SQL_SUCCESS) { SDWORD cbOwnerID, cbName; long ownerID; char fullName[51]; SQLBindCol(hstmt, 1, SQL_C_LONG, &ownerID, 0, &cbOwnerID); SQLBindCol(hstmt, 2, SQL_C_CHAR, fullName, 51, &cbName); retcode = SQLFetch(hstmt); while (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { long newID = (ownerID / 100L) * 100L; for (register i = 0; i < min (sNumMatchingSystems, 50); ++i) if (sMatchingSystemID[i] == newID) break; if (i >= min (sNumMatchingSystems, 50)) { if (sNumMatchingSystems < 50) { sMatchingSystemID [sNumMatchingSystems] = newID; if (cbName) strcpy (sMatchingSystemName[sNumMatchingSystems], fullName); else sMatchingSystemName[sNumMatchingSystems][0] = '\0'; } ++ sNumMatchingSystems; } retcode = SQLFetch(hstmt); } if (sNumMatchingSystems > 0) return true; // "name" isn't a proper name, so search for matching catalog number. // Parse name according to first space. char catBuf[512], *numPtr; strncpy (catBuf, name, 511); catBuf[511] = '\0'; numPtr = strchr (catBuf, ' '); if (numPtr) { *numPtr = '\0'; // a poor-man's strtok() ++numPtr; retcode = SQLFreeStmt (hstmt, SQL_CLOSE); sprintf (buffer, "SELECT OwnerID FROM CatalogNumbers " "WHERE CatAbbrev = '%s' AND Value = '%s'", catBuf, numPtr); retcode = SQLExecDirect (hstmt, (unsigned char *) buffer, SQL_NTS); if (retcode == SQL_SUCCESS) { SQLBindCol(hstmt, 1, SQL_C_LONG, &ownerID, 0, &cbOwnerID); retcode = SQLFetch(hstmt); if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { sMatchingSystemID [sNumMatchingSystems++] = (ownerID / 100L) * 100L; return true; } } } } return false; } static bool SystemExists (HSTMT hstmt, long systemID) { if (systemID > 0 && (systemID % 100) == 0) { char buffer[512]; RETCODE retcode; retcode = SQLFreeStmt (hstmt, SQL_CLOSE); sprintf (buffer, "SELECT COUNT(*) FROM Systems WHERE ID=%ld", systemID); retcode = SQLExecDirect (hstmt, (unsigned char *) buffer, SQL_NTS); if (retcode == SQL_SUCCESS) { int count; SDWORD cbCount; SQLBindCol (hstmt, 1, SQL_C_LONG, &count, 0, &cbCount); retcode = SQLFetch(hstmt); if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) return count > 0; } } return false; } static bool DisplayAllFoundMatches (HSTMT hstmt, const char *name) { FetchCatalogNames (hstmt); printf ("Content-type: text/html%c%c", 10, 10); puts (""); puts (""); puts (""); puts (""); puts ("ISDB search results"); puts (""); puts (""); printf ("

%d stars found with a name matching " ""%s":

\n", sNumMatchingSystems, name); if (sNumMatchingSystems > 50) printf ("
Only the first 50 matches will be shown.\n
"); for (register i = 0; i < min (sNumMatchingSystems, 50); ++i) { char buffer[122]; printf ("
%s", sMatchingSystemID[i], sMatchingSystemName[i]); FetchMainSystemName (hstmt, sMatchingSystemID[i], buffer); if (strcmp (sMatchingSystemName[i], buffer)) printf (" (%s)", buffer); printf ("\n"); } DisposeCatalogNames(); return true; } int main() { HENV henv; HDBC hdbc; HSTMT hstmt; RETCODE retcode; int mainRetCode = -1; long systemID = 0; #ifdef _DEBUG // const char *szQueryString = "Name=HD+89744"; // const char *szQueryString = "Name=Alpha+Centauri"; const char *szQueryString = "ID=136700"; // const char *szQueryString = "Name=Sirius"; #else const char *szQueryString = getenv ("QUERY_STRING"); #endif const char *searchName = NULL, *szID = NULL, *searchCat = NULL, *catNo = NULL; char searchNameBuffer[32]; // if given a catalog & number instead of a name if (!szQueryString) { printf ("Content-type: text/plain\n\n"); printf ("This CGI program requires a query string. None was found.\n"); return -1; } ParseToList (szQueryString); if ((szID = QueryVariable::FindName ("ID")) != NULL) { systemID = atol (szID); if (systemID <= 0 || (systemID % 100)) { puts ("Content-type: text/plain\n"); puts ("Invalid \"ID=\" clause. ID must be a positive multiple of 100."); return -1; } } else if ((searchName = QueryVariable::FindName ("Name")) != NULL) { } else if ((searchCat = QueryVariable::FindName ("Catalog")) != NULL && (catNo = QueryVariable::FindName ("CatNo")) != NULL) { strncpy (searchNameBuffer, searchCat, 10); searchNameBuffer[10] = '\0'; strcat (searchNameBuffer, " "); strncat (searchNameBuffer, catNo, 20); searchName = searchNameBuffer; } else { puts ("Content-type: text/plain\n"); puts ("Invalid query string. Must contain one of the following sets of clauses:"); puts ("\"ID=\""); puts ("\"Name=\""); puts ("\"Catalog=\" and \"CatNo=\""); return -1; } if (!systemID && (!searchName || !searchName[0])) { puts ("Content-type: text/plain\n"); puts ("Please enter one or more search criteria."); return -1; } retcode = SQLAllocEnv(&henv); if (retcode == SQL_SUCCESS) { retcode = SQLAllocConnect(henv, &hdbc); if (retcode == SQL_SUCCESS) { SQLSetConnectOption(hdbc, SQL_LOGIN_TIMEOUT, 2); SQLSetConnectOption(hdbc, SQL_ACCESS_MODE, SQL_MODE_READ_ONLY); // Note: for the following statement to succeed, the system // running this code MUST have a System DSN of "ISDB" // configured to use the MS Access 97 driver with a "Database" // of C:\ISDB\ISDB.MDB in the ODBC32 Control Panel applet. retcode = SQLConnect(hdbc, (unsigned char *) "ISDB", SQL_NTS, (unsigned char *) "", 0, (unsigned char *) "", 0); if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { retcode = SQLAllocStmt(hdbc, &hstmt); if (retcode == SQL_SUCCESS) { if (!systemID) { if (!SearchName (hstmt, searchName)) { printf ("Content-type: text/html%c%c", 10, 10); puts (""); puts (""); puts (""); puts (""); puts ("ISDB search results"); puts (""); puts (""); printf ("No star name matching \"%s\" found.\n", searchName); puts ("\n"); } if (sNumMatchingSystems > 1) DisplayAllFoundMatches (hstmt, searchName); else systemID = sMatchingSystemID[0]; } else if (!SystemExists (hstmt, systemID)) { printf ("Content-type: text/html%c%c", 10, 10); puts (""); puts (""); puts (""); puts (""); puts ("ISDB system ID lookup search results"); puts (""); puts (""); printf ("No star system with an ID of %d exists in the database.\n", systemID); puts ("\n"); systemID = 0; } if (systemID && display_id (hdbc, hstmt, systemID)) mainRetCode = 0; SQLFreeStmt(hstmt, SQL_DROP); } else { printf ("Content-type: text/plain\n\n"); printf ("Internal error: could not allocate statement." " Please try again.\n"); } SQLDisconnect(hdbc); } else { char szSqlState [20]; char szErrorMsg [SQL_MAX_MESSAGE_LENGTH]; SDWORD fNativeError; SWORD cbErrorMsg; printf ("Content-type: text/plain\n\n"); printf ("Internal error: SQLConnect() failed!!\n"); retcode = SQLError (henv, hdbc, SQL_NULL_HSTMT, (UCHAR *) szSqlState, &fNativeError, (UCHAR *) szErrorMsg, SQL_MAX_MESSAGE_LENGTH - 1, &cbErrorMsg); if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { printf ("SQLSTATE = '%s'\n", szSqlState); printf ("Error message = '%s'\n", szErrorMsg); } } SQLFreeConnect(hdbc); } else { printf ("Content-type: text/plain\n\n"); printf ("Internal error: could not allocate connection." " Please try again.\n"); } SQLFreeEnv(henv); } else { printf ("Content-type: text/plain\n\n"); printf ("Internal error: could not allocate environment." " Please try again.\n"); } return mainRetCode; }