home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: InfoMgt / InfoMgt.zip / dbadm101.zip / dbadmin.c < prev    next >
C/C++ Source or Header  |  1999-02-07  |  51KB  |  1,656 lines

  1. /* 
  2. **    dbadmin.c    -
  3. **
  4. **
  5. ** Copyright (c) 1996 James E. Harrell, Jr.
  6. **
  7. ** This software is provided "as is" without any expressed or implied warranty.
  8. **
  9. **
  10. */
  11.  
  12. #include <stdio.h>
  13. #include <sys/types.h>
  14. #include "cgic.h"
  15. #include "msql.h"
  16. #include "dbadmin.h"
  17. #include <string.h>
  18.  
  19. char *thetable;
  20. int table_name_length;
  21. char *thedb;
  22. int  name_length;
  23.  
  24. int       state;
  25. int       action;
  26. int       numfields;
  27. char      *fieldnames;
  28. int       sock;
  29. char      field[MAX_FIELDS][MAX_FIELDNAME_LEN];
  30. char      type[MAX_FIELDS][5];
  31. char      lengthStr[MAX_FIELDS][5];
  32. char      notnul[MAX_FIELDS][2];
  33. char      key[MAX_FIELDS][2];
  34. char      operation[5];
  35. m_result  *res;
  36. m_result  *res2;
  37. m_row     cur;
  38. m_field   *curField;
  39. int       dberror;
  40. char      qbuf[MAX_TEXTQUERY_LEN];
  41. cgiFormResultType cgiError;
  42.  
  43. void unimplementedOption(void);
  44. void giveDebugInfo(void);
  45. int  getState(void);
  46. void giveTitle(void);
  47. void connectMSQL(void);
  48. void getNewDBName(void);
  49. void connectDB(void);
  50. void connectTable(void);
  51. void doTitlePage(void);
  52. void doAdminSelection(void);
  53. void showDatabases(int);
  54. void addDatabase(void);
  55. void doAddDB(void);
  56. void doRemoveDB(void);
  57. void removeDatabase(void);
  58. void modifyStructure(void);
  59. void doModifyStructure(void);
  60. void showCurrentTables(void);
  61. void giveAddTable(void);
  62. void doRemoveTable(void);
  63. void doAddTable(void);
  64. void addTableNow(void);
  65. void getFields(void);
  66. void viewUpdateInfo(void);
  67. void doTableSelection(void);
  68. void giveSearch(void);
  69. void giveInsert(void);
  70. void showSelectData(void);
  71. void giveBackQueryPage(void);
  72.  
  73. void showTables(void);
  74. void giveCannedSelect(void);
  75. void giveTextQuery(void);
  76. void doTextQuery(void);
  77. void doCannedQuery(void);
  78. void addCannedQuery(void);
  79. void giveInsertForm(void);
  80. void searchRecords(void);
  81. void giveSearchForm(void);
  82. void returnSearch(void);
  83. void getSearchSpec(void);
  84. void doSearchQuery(void);
  85. void showSelectDeleteData(void);
  86. void deleteSearchItem(void);
  87. void performDelete(void);
  88.  
  89. void updateSearchItem(void);
  90. void performUpdate(void);
  91. void giveBackOriginalQuery(void);
  92.  
  93. void giveInitialActions(void);
  94. void giveButtonBar(void);
  95.  
  96. int cgiMain() {
  97.     cgiHeaderContentType("text/html");
  98.     fprintf(cgiOut, "<HTML><HEAD>\n");
  99.     fprintf(cgiOut, "<TITLE>James Harrell's Database Administration Toolkit</TITLE></HEAD>\n");
  100.     fprintf(cgiOut, "<BODY>\n");
  101.  
  102.         switch (getState())
  103.         {
  104.           case 0: doTitlePage();
  105.                   break;
  106.  
  107.           case 1: doAdminSelection();
  108.                   break;
  109.  
  110.           case 2: doAddDB();                    /* ADD DATABASE */
  111.                   break;
  112.  
  113.           case 3: doRemoveDB();                 /* REMOVE DATABASE */
  114.                   break;
  115.  
  116.           case 4: doModifyStructure();          /* MODIFY TABLES */
  117.                   break;
  118.  
  119.           case 5: doRemoveTable();              /* DELETE TABLE */
  120.                   break;
  121.  
  122.           case 6: doAddTable();                 /* ADD TABLE FORM */
  123.                   break;
  124.  
  125.           case 7: addTableNow();                /* REALLY ADD TABLE */
  126.                   break;
  127.  
  128.           case 8: doTableSelection();
  129.                   break;
  130.  
  131.           case 9: doTextQuery();        /* Submit Hand query */
  132.                   break;
  133.  
  134.           case 10: doCannedQuery();             /* Add info to table, etc. */
  135.                   break;
  136.  
  137.           case 11: addCannedQuery();             /* Do the add */
  138.                    break;
  139.  
  140.           case 12: searchRecords();        /* Perform canned search */
  141.                    break;
  142.  
  143.           case 14: returnSearch();        /* Return data */
  144.                    break;
  145.  
  146.           case 15: deleteSearchItem();        /* Return data */
  147.                    break;
  148.  
  149.           case 16: updateSearchItem();        /* Return data */
  150.                    break;
  151.  
  152.       default: unimplementedOption();
  153.         }
  154.         giveButtonBar();
  155. #ifdef DEBUG
  156.         giveDebugInfo();
  157. #endif
  158.     fprintf(cgiOut, "</BODY></HTML>\n");
  159.     return 0;
  160. }
  161.  
  162. void giveDebugInfo(void)
  163. {
  164.   fprintf(cgiOut,"<HR>\n");
  165.   fprintf(cgiOut,"<CENTER><H3>DEBUG INFORMATION</H3></CENTER>\n");
  166.   fprintf(cgiOut,"State = %d\n",state);
  167.   fprintf(cgiOut,"<HR>\n");
  168. }
  169.  
  170. int getState(void)
  171. {
  172.   cgiFormInteger("state",&state,0);
  173.   return state;
  174. }
  175.  
  176. void connectMSQL(void)
  177. {
  178. #ifdef DEBUG
  179.   fprintf(cgiOut,"<BR>Connecting to msqld on localhost.\n<BR>");
  180. #endif
  181.   if ((sock = msqlConnect(NULL)) == -1)
  182.   {
  183.     fprintf(cgiOut,"\nError connecting to database : <BR>\n%s\n\n",msqlErrMsg);
  184.     giveButtonBar();
  185.     exit(1);
  186.   }
  187. }
  188.  
  189. void getNewDBName(void)
  190. {
  191. #ifdef DEBUG
  192.   fprintf(cgiOut,"<BR>Getting space requirements for database name.\n<BR>\n");
  193. #endif
  194.  if ((cgiError=cgiFormStringSpaceNeeded("thedb",&name_length))==cgiFormNotFound)
  195.     { 
  196.     fprintf(cgiOut,"You have requested to create a database without\n");
  197.     fprintf(cgiOut,"specifying a database name!\n");
  198.     giveButtonBar();
  199.     exit(1);
  200.     }
  201.   #ifdef DEBUG
  202.   fprintf(cgiOut,"<BR>Currently allocating %d bytes of memory.<BR>\n",name_length);
  203.   #endif
  204.   thedb = (char *)malloc(sizeof(char)*name_length);
  205.   cgiError=cgiFormString("thedb",thedb,name_length);
  206. }
  207.  
  208. void connectDB(void)
  209. {
  210. #ifdef DEBUG
  211.   fprintf(cgiOut,"<BR>Getting space requirements for database name.\n<BR>\n");
  212. #endif
  213.  if ((cgiError=cgiFormStringSpaceNeeded("thedb",&name_length))==cgiFormNotFound)
  214.     { 
  215.     fprintf(cgiOut,"You have requested to connect to a database without\n");
  216.     fprintf(cgiOut,"specifying a database name!\n");
  217.     giveButtonBar();
  218.     exit(1);
  219.     }
  220.   #ifdef DEBUG
  221.   fprintf(cgiOut,"<BR>Currently allocating %d bytes of memory.<BR>\n",name_length);
  222.   #endif
  223.   thedb = (char *)malloc(sizeof(char)*name_length);
  224.   cgiError=cgiFormString("thedb",thedb,name_length);
  225.   if(msqlSelectDB(sock,thedb) < 0)
  226.     {
  227.     fprintf(cgiOut,"ERROR selecting database %s<BR>\n",thedb);
  228.     fprintf(cgiOut,"\n%s<BR>\n\n",msqlErrMsg);
  229.     msqlClose(sock);
  230.     giveButtonBar();
  231.     exit(1);
  232.     }
  233.   #ifdef DEBUG
  234.   fprintf(cgiOut,"<BR>Connected to database %s.\n<BR>",thedb);
  235.   #endif
  236. }
  237.  
  238. void connectTable(void)
  239. {
  240.   if ((cgiError=cgiFormStringSpaceNeeded("thetable",&table_name_length)) ==
  241.     cgiFormNotFound)
  242.     {
  243.     fprintf(cgiOut,"You have requested to connect to a table in database %s\n",thedb);
  244.     fprintf(cgiOut,"without specifying the table!\n");
  245.     giveButtonBar();
  246.     exit(1);
  247.     }
  248.   thetable = (char *)malloc(sizeof(char)*table_name_length);
  249.   cgiError=cgiFormString("thetable",thetable,table_name_length);
  250.   #ifdef DEBUG
  251.   fprintf(cgiOut,"<BR>All queries currently apply to table %s.<BR>\n",thetable);
  252.   #endif
  253. }
  254.  
  255. void giveButtonBar(void)
  256. {
  257.   fprintf(cgiOut,"<HR>\n");
  258.   fprintf(cgiOut,"<CENTER>\n");
  259.   fprintf(cgiOut,"<TABLE CELLPADDING=0 BORDER=4>\n");
  260.   fprintf(cgiOut,"<TR>");
  261.   fprintf(cgiOut,"<TH WIDTH=20%%><A HREF=\"%s/dbadmin?state=-1\">CONNECT SERVER</A></TH>\n",RELPATH); 
  262.   fprintf(cgiOut,"<TH WIDTH=20%%><A HREF=\"%s/dbadmin\">CONNECT DATABASE</A></TH>\n",RELPATH);
  263.   fprintf(cgiOut,"<TH WIDTH=20%%><A HREF=\"%s/dbadmin?state=1&action=1\">ADD DATABASES</A></TH>\n",RELPATH);
  264.   fprintf(cgiOut,"<TH WIDTH=20%%><A HREF=\"%s/dbadmin?state=1&action=2\">REMOVE DATABASES</A></TH>\n",RELPATH);
  265.   /* fprintf(cgiOut,"<TH WIDTH=20%%><A HREF=\"%s/dbadmin?state=1&action=3\">VIEW/MODIFY STRUCTURE</A></TH>\n",RELPATH); */
  266.   /* fprintf(cgiOut,"<TH WIDTH=20%%><A HREF=\"%s/dbadmin?state=1&action=4\">VIEW/MODIFY DATABASE</A></TH>\n",RELPATH); */
  267.   fprintf(cgiOut,"</TR>");
  268.   fprintf(cgiOut,"</TABLE><HR>\n");
  269. }
  270.  
  271. /* -------------------------- UNIMPLEMENTED ACTIONS --------------------- */
  272. /*                                STATE = -1                              */
  273. void unimplementedOption(void)
  274. {
  275.   giveTitle();
  276.   fprintf(cgiOut,"<HR><H3><CENTER>YOU HAVE REQUESTED AN UNIMPLEMENTED\n");
  277.   fprintf(cgiOut,"OPTION. PLEASE LOOK FOR THIS FUNCTIONALITY IN A FUTURE\n");
  278.   fprintf(cgiOut,"RELEASE...</CENTER></H3><HR>\n");
  279. }
  280.  
  281.  
  282. /* -------------------------- INITIAL ACTIONS PAGE ---------------------- */
  283. /*                                STATE = 0                               */
  284.  
  285. void doTitlePage(void)
  286. {
  287.   giveTitle();
  288.   connectMSQL();
  289.   giveInitialActions();
  290.   msqlClose(sock);
  291. }
  292.  
  293. void giveTitle(void) 
  294. {
  295. #ifdef DEBUG
  296.   fprintf(cgiOut,"<BR>Now entering \"giveTitle\"<BR>\n");
  297. #endif
  298.   fprintf(cgiOut,"<H1>mSQL DataBase Administration %s</H1>\n",VERSION);
  299.   fprintf(cgiOut,"<HR>\n");
  300.   fprintf(cgiOut,"<CENTER><EM>This database administration tool is NOT\n");
  301.   fprintf(cgiOut,"freeware. Please license any distribution. See the file\n");
  302.   fprintf(cgiOut,"license.doc for further information! ALL commercial sites\n");
  303.   fprintf(cgiOut,"are required to register their copy!</EM></CENTER><HR>\n");
  304. }
  305.  
  306. void giveInitialActions(void)
  307. {
  308.   fprintf(cgiOut,"<FORM METHOD=POST ACTION=%s/dbadmin>\n",RELPATH);
  309.   fprintf(cgiOut,"<H3>Please select a database:</H3>\n");
  310.   showDatabases(RADIO_LIST);
  311.   fprintf(cgiOut,"<H3>Please select an action:</H3>\n");
  312.   fprintf(cgiOut,"<DD><INPUT TYPE=RADIO NAME=\"state\" VALUE=8 CHECKED> Query / Update Database...<BR>\n");
  313.   fprintf(cgiOut,"<DD><INPUT TYPE=RADIO NAME=\"state\" VALUE=4> Add / Remove Table Definitions...<BR>\n");
  314.   fprintf(cgiOut,"<P><CENTER><INPUT TYPE=SUBMIT VALUE=\"Connect to Database...\"></CENTER>\n");
  315.   fprintf(cgiOut,"</FORM>\n<HR><HR>\n");
  316. }
  317.  
  318. /* -------------------------- DO ADMIN SELECTION --------------------------- */
  319. /*                                STATE = 1                                  */
  320.  
  321. void doAdminSelection(void)
  322. {
  323.   giveTitle();
  324.   connectMSQL();
  325.   cgiError=cgiFormInteger("action",&action,0);
  326.   switch(action)
  327.     {
  328.     case ADD_DB: addDatabase();
  329.       break;
  330.     case REM_DB: removeDatabase();
  331.       break;
  332.     default : fprintf(cgiOut,"\nERROR : No Action Specified!<BR>\n");
  333.     }
  334. }
  335.  
  336. void addDatabase(void)
  337. {
  338.   fprintf(cgiOut,"<H3>The following databases currently exist:</H3>\n");
  339.   showDatabases(NORMAL);
  340.   fprintf(cgiOut,"<P><H3>Add Database:</H3>\n");
  341.   fprintf(cgiOut,"<FORM METHOD=POST ACTION=%s/dbadmin>",RELPATH);
  342.   fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=state VALUE=2>");
  343.   fprintf(cgiOut,"<CENTER><TABLE BORDER=0>\n");
  344.   fprintf(cgiOut,"<TR WIDTH=85%%>\n");
  345.   fprintf(cgiOut,"<TD ALIGN=CENTER WIDTH=33%%>New Database Name:</TD>\n");
  346.   fprintf(cgiOut,"<TD ALIGN=CENTER WIDTH=33%%><INPUT NAME=\"thedb\" SIZE=25></TD>\n");
  347.   fprintf(cgiOut,"<TD ALIGN=CENTER WIDTH=33%%><INPUT TYPE=submit VALUE=\"Add Database\"></TD>\n");
  348.   fprintf(cgiOut,"</TR></TABLE></CENTER>\n");
  349. }
  350.  
  351. void removeDatabase(void)
  352. {
  353.   fprintf(cgiOut,"<H3>Remove Database:</H3>\n");
  354.   fprintf(cgiOut,"<FORM METHOD=POST ACTION=%s/dbadmin>",RELPATH);
  355.   fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=state VALUE=3>");
  356.   fprintf(cgiOut,"Please select a database to remove:\n<BR>\n");
  357.   connectMSQL();
  358.   showDatabases(RADIO_LIST);
  359.   fprintf(cgiOut,"<CENTER><H4>THIS OPERATION CANNOT BE UNDONE!!</H4>\n");
  360.   fprintf(cgiOut,"<INPUT TYPE=SUBMIT VALUE=\"Remove Database\"></CENTER>\n<BR>\n");
  361.   msqlClose(sock);
  362. }
  363.  
  364. void modifyStructure(void)
  365. {
  366.   fprintf(cgiOut,"<H3>View/Modify Database Structure:</H3>\n");
  367.   fprintf(cgiOut,"<FORM METHOD=POST ACTION=%s/dbadmin>",RELPATH);
  368.   fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=state VALUE=4>");
  369.   fprintf(cgiOut,"Please select a database to view/modify structure:\n<BR>\n");
  370.   connectMSQL();
  371.   showDatabases(RADIO_LIST);
  372.   fprintf(cgiOut,"<INPUT TYPE=SUBMIT VALUE=\"View/Modify Structure\">\n<BR>\n");
  373.   msqlClose(sock);
  374. }
  375.  
  376. void viewUpdateInfo(void)
  377. {
  378.   fprintf(cgiOut,"<H3>View or Query Database:</H3>\n");
  379.   fprintf(cgiOut,"<FORM METHOD=POST ACTION=%s/dbadmin>",RELPATH);
  380.   fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=state VALUE=8>");
  381.   fprintf(cgiOut,"Please select a database to view or query:\n<BR>\n");
  382.   connectMSQL();
  383.   showDatabases(RADIO_LIST);
  384.   fprintf(cgiOut,"<INPUT TYPE=SUBMIT VALUE=\"Connect Database\">\n<BR>\n");
  385.   msqlClose(sock);
  386. }
  387.  
  388. void showDatabases(int listVersion)
  389. {
  390. int x=0;
  391.   res = msqlListDBs(sock);
  392.   if (!res)
  393.     {
  394.     fprintf(cgiOut,"\nError : Couldn't get database list!\n<BR>\n");
  395.     msqlClose(sock);
  396.     giveButtonBar();
  397.     exit(1);
  398.     }
  399.   if (listVersion==NORMAL) { fprintf(cgiOut,"<UL>\n"); }
  400.   while((cur = msqlFetchRow(res)))
  401.     { 
  402.     x++;
  403.     switch(listVersion)
  404.       { 
  405.       case NORMAL: fprintf(cgiOut,"<LI> %s<BR>\n",cur[0]);
  406.            break;
  407.       case RADIO_LIST: fprintf(cgiOut,"<DD><INPUT TYPE=RADIO NAME=\"thedb\" VALUE=\"%s\"",cur[0]);
  408.                        if (x==1) fprintf(cgiOut," CHECKED");
  409.                        fprintf(cgiOut,"> %s<BR>\n",cur[0]);
  410.                        
  411.            break;
  412.       default: fprintf(cgiOut,"%s<BR>\n");
  413.       }
  414.     }
  415.   if (listVersion==NORMAL) { fprintf(cgiOut,"</UL>\n"); }
  416.   msqlFreeResult(res);
  417. }
  418.  
  419. /* --------------------------- DO ADD DATABASE ---------------------------- */
  420. /*                               STATE = 2                                  */
  421. void doAddDB(void)
  422. {
  423.   giveTitle();
  424.   connectMSQL();
  425.   getNewDBName();
  426.  
  427.   if(msqlCreateDB(sock,thedb) < 0)
  428.       {
  429.       fprintf(cgiOut,"\n<BR>mSQL Command Failed!\n<BR>Server Error = %s\n<BR>\n",msqlErrMsg);
  430.       msqlClose(sock);
  431.       giveButtonBar();
  432.       exit(1);
  433.       }
  434.      else
  435.       { fprintf(cgiOut,"<BR>Database \"%s\" created.<BR>\n",thedb); }
  436.   addDatabase();  
  437.   msqlClose(sock);
  438. }
  439.  
  440.  
  441. /* -------------------------- REMOVE DATABASE ----------------------------- */
  442. /*                               STATE = 3                                  */
  443.  
  444. void doRemoveDB(void)
  445. {
  446.   giveTitle();
  447.   connectMSQL();
  448.   connectDB();
  449.  
  450.   if(msqlDropDB(sock,thedb) < 0)
  451.     {     
  452.     fprintf(cgiOut,"\nmSQL Command failed!\n<BR>Server error = %s\n<BR>\n",msqlErrMsg);
  453.     msqlClose(sock);
  454.     giveButtonBar();
  455.     exit(1);
  456.     }
  457.    else
  458.     { fprintf(cgiOut,"Database \"%s\" dropped!\n<BR>\n",thedb); }
  459.   removeDatabase();
  460.   msqlClose(sock);
  461. }
  462.  
  463. /* ----------------------- MODIFY TABLE STRUCTURE ------------------------- */
  464. /*                               STATE = 4                                  */
  465.  
  466. void doModifyStructure(void)
  467. {
  468.   giveTitle();
  469.   connectMSQL();
  470.   connectDB();
  471.  
  472.   if (msqlSelectDB(sock,thedb) < 0)
  473.     {
  474.     fprintf(cgiOut,"ERROR selecting database %s\n<BR>\n",thedb);
  475.     fprintf(cgiOut,"\n%s<BR>\n\n",msqlErrMsg);
  476.     msqlClose(sock);
  477.     giveButtonBar();
  478.     exit(1);
  479.     }
  480.    else
  481.     {
  482. /*  if TABLESEXIST */
  483.     showCurrentTables();
  484.     giveAddTable();
  485.     }
  486.   msqlClose(sock);
  487. }
  488.  
  489. void showCurrentTables(void)
  490. {
  491.   fprintf(cgiOut,"<H3>The following table definitions exist for database: %s</H3>",thedb);
  492.   fprintf(cgiOut,"<HR>\n");
  493.   res = msqlListTables(sock);
  494.   if (!res)
  495.     {
  496.    fprintf(cgiOut,"\nERROR : Unable to list tables in database %s<BR>\n",thedb);
  497.     giveButtonBar();
  498.     exit(1);
  499.     }
  500.    else
  501.     {
  502.     dberror=msqlNumRows(res);
  503.     if (dberror<1)
  504.       { fprintf(cgiOut,"<CENTER><H3>No tables in database.</H3></CENTER>\n<BR>\n"); }
  505.     else 
  506.       {
  507.       while((cur=msqlFetchRow(res)))
  508.         {
  509.         res2 = msqlListFields(sock,cur[0]);
  510.         if (!res2)
  511.           {
  512.           fprintf(cgiOut,"ERROR : Couldn't find %s in %s!<BR>\n",cur[0],thedb);
  513.           msqlFreeResult(res);
  514.       giveButtonBar();
  515.           exit(1);
  516.           }
  517.          else
  518.           {
  519.           fprintf(cgiOut,"<BR><CENTER>\n");
  520.           fprintf(cgiOut,"<TABLE CELLPADDING=3 BORDER=5>\n");
  521.           fprintf(cgiOut,"<TR WIDTH=80%%><TH COLSPAN=5>TABLE: %s</TH></TR>\n",cur[0]);
  522.           fprintf(cgiOut,"<TR><TH WIDTH=15%%>FIELD</TH>");
  523.           fprintf(cgiOut,"<TH WIDTH=15%%>TYPE</TH>");
  524.           fprintf(cgiOut,"<TH WIDTH=15%%>LENGTH</TH>");
  525.           fprintf(cgiOut,"<TH WIDTH=15%%>NOT NULL</TH>");
  526.           fprintf(cgiOut,"<TH WIDTH=15%%>KEY</TH></TR>");
  527.           while((curField = msqlFetchField(res2)))
  528.             {
  529.             fprintf(cgiOut,"<TR>\n");
  530.             fprintf(cgiOut,"<TH>%s</TH>\n",curField->name);
  531.             fprintf(cgiOut,"<TD>");
  532.             switch(curField->type)
  533.               {
  534.               case INT_TYPE: fprintf(cgiOut,"int");
  535.                    break;
  536.               case CHAR_TYPE: fprintf(cgiOut,"char");
  537.                    break;
  538.               case REAL_TYPE: fprintf(cgiOut,"real");
  539.                    break;
  540.               default: fprintf(cgiOut,"Unknown");
  541.                    break;
  542.               }
  543.             fprintf(cgiOut,"</TD>\n");
  544.             fprintf(cgiOut,"<TD>%d</TD>\n",curField->length);
  545.               /* fprintf(cgiOut,"<TD>PLACEHOLDER</TD>\n"); */
  546.             fprintf(cgiOut,"<TD>%s</TD>\n", IS_NOT_NULL(curField->flags)? "Y":"N");
  547.             /* fprintf(cgiOut,"<TD>%s</TD>\n", IS_PRI_KEY(curField->flags)? "Y":"N"); */
  548.             fprintf(cgiOut,"</TR>");
  549.             }
  550.           fprintf(cgiOut,"</TABLE><BR>\n");
  551.           fprintf(cgiOut,"<FORM METHOD=POST ACTION=%s/dbadmin>\n",RELPATH);
  552.           fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"thedb\" VALUE=\"%s\">\n",thedb);
  553.           fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"thetable\" VALUE=%s>\n",cur[0]);
  554.           fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"state\" VALUE=5>\n");
  555.           fprintf(cgiOut,"<INPUT TYPE=SUBMIT VALUE=\"REMOVE TABLE\">\n");
  556.           fprintf(cgiOut,"</FORM>\n");
  557.           fprintf(cgiOut,"<HR WIDTH=75%%>\n");
  558.           fprintf(cgiOut,"</CENTER>\n");
  559.           }
  560.         }
  561.       msqlFreeResult(res2);
  562.       }
  563.     msqlFreeResult(res);
  564.     }
  565. }
  566.  
  567. void giveAddTable(void)
  568. {
  569.   fprintf(cgiOut,"<HR WIDTH=90%%><HR WIDTH=80%%>\n");
  570.   fprintf(cgiOut,"<H3>Add table definition with:</H3>\n");
  571.   fprintf(cgiOut,"<FORM METHOD=POST ACTION=%s/dbadmin>\n",RELPATH);
  572.   fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"state\" VALUE=6>\n");
  573.   fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"thedb\" VALUE=\"%s\">\n",thedb);
  574.   fprintf(cgiOut,"Number of fields = ");
  575.   fprintf(cgiOut,"<INPUT NAME=\"numfields\" SIZE=2>\n");
  576.   fprintf(cgiOut,"<INPUT TYPE=SUBMIT VALUE=\"CREATE TABLE...\">\n");
  577.   fprintf(cgiOut,"</FORM>\n");
  578. }
  579.  
  580.  
  581. /* ------------------------------- REMOVE TABLE --------------------------- */
  582. /*                                  STATE = 5                               */
  583. void doRemoveTable(void)
  584. {
  585.   giveTitle();
  586.   connectMSQL();
  587.   connectDB();
  588.   connectTable(); 
  589.  
  590.   #ifdef DEBUG
  591.   fprintf(cgiOut,"\n<BR>Table %s being removed from %s\n",thetable,thedb);
  592.   #endif
  593.   strcpy(qbuf,"DROP TABLE ");
  594.   strcat(qbuf,thetable);
  595.   #ifdef DEBUG
  596.   fprintf(cgiOut,"Query = %s<BR>\n",qbuf);
  597.   #endif
  598.   if (msqlQuery(sock,qbuf) == -1)
  599.     {
  600.     fprintf(cgiOut,"ERROR: unable to drop table %s from %s.<BR>\n",thetable,thedb);
  601.     fprintf(cgiOut,"Invalid query = %s<BR>\n",qbuf);
  602.     msqlClose(sock);
  603.     giveButtonBar();
  604.     exit(1);
  605.     }
  606.    else
  607.     { fprintf(cgiOut,"\n<BR>Table %s removed from %s.\n",thetable,thedb); }
  608.     
  609.   showCurrentTables();
  610.   giveAddTable();
  611.   msqlClose(sock);
  612. }
  613.  
  614.  
  615. /* -------------------------------- ADD TABLE ----------------------------- */
  616. /*                                  STATE = 6                               */
  617. void doAddTable(void)
  618. {
  619. int x;
  620.  
  621.   giveTitle();
  622.   connectMSQL();
  623.   connectDB();
  624.  
  625.     cgiError=cgiFormIntegerBounded("numfields",&numfields,1,MAX_FIELDS,0);
  626.     if (cgiError==cgiFormSuccess)
  627.       { 
  628.       fprintf(cgiOut,"<H3>Please enter new table definition:</H3><BR>\n");
  629.       fprintf(cgiOut,"<CENTER>\n");
  630.       fprintf(cgiOut,"<FORM METHOD=POST ACTION=%s/dbadmin>\n",RELPATH);
  631.       fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=state VALUE=7>\n");
  632.       fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"thedb\" VALUE=\"%s\">\n",thedb);
  633.       fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"numfields\" VALUE=%d>\n",numfields);
  634.       fprintf(cgiOut,"<TABLE BORDER=0><TR><TH>Table Name:</TH></TR>\n");
  635.       fprintf(cgiOut,"<TR><TD><INPUT NAME=\"thetable\" VALUE=\"(new_table_name)\" SIZE=25></TD></TR></TABLE>\n");
  636.       fprintf(cgiOut,"<TABLE CELLPADDING=3 BORDER=4>\n");
  637.       fprintf(cgiOut,"<TR>\n");
  638.       fprintf(cgiOut,"<TH WIDTH=15%%>FIELD\n");
  639.       fprintf(cgiOut,"<TH WIDTH=15%%>TYPE\n");
  640.       fprintf(cgiOut,"<TH WIDTH=15%%>LENGTH\n");
  641.       fprintf(cgiOut,"<TH WIDTH=15%%>NOT NULL\n");
  642.       fprintf(cgiOut,"<TH WIDTH=15%%>KEY\n");
  643.       fprintf(cgiOut,"</TR>\n");
  644.       for(x=1; x<=numfields; x++)
  645.         {
  646.         fprintf(cgiOut,"<TR>\n");
  647.         fprintf(cgiOut,"<TD ALIGN=CENTER><INPUT NAME=\"field%d\" VALUE=\"field%d\" SIZE=25></TD>\n",x,x);
  648.         fprintf(cgiOut,"<TD ALIGN=CENTER><SELECT NAME=\"type%d\">\n",x);
  649.             fprintf(cgiOut,"<OPTION>INT\n");
  650.             fprintf(cgiOut,"<OPTION>CHAR\n");
  651.             fprintf(cgiOut,"<OPTION>REAL\n");
  652.             fprintf(cgiOut,"</SELECT>\n");
  653.         fprintf(cgiOut,"</TD>\n");
  654.         fprintf(cgiOut,"<TD ALIGN=CENTER><INPUT NAME=\"lengthStr%d\" VALUE=25 SIZE=5></TD>\n",x);
  655.         fprintf(cgiOut,"<TD ALIGN=CENTER><SELECT NAME=\"notnul%d\">\n",x);
  656.           if (x==1)
  657.             {
  658.             fprintf(cgiOut,"<OPTION>Y\n");
  659.             fprintf(cgiOut,"<OPTION>N\n");
  660.             }
  661.            else
  662.             {
  663.             fprintf(cgiOut,"<OPTION>N\n");
  664.             fprintf(cgiOut,"<OPTION>Y\n");
  665.             }
  666.             fprintf(cgiOut,"</SELECT>\n");
  667.         fprintf(cgiOut,"</TD>\n");
  668.         fprintf(cgiOut,"<TD ALIGN=CENTER><SELECT NAME=\"key%d\">\n",x);
  669.           if (x==1)
  670.             {
  671.             fprintf(cgiOut,"<OPTION>Y\n");
  672.             fprintf(cgiOut,"<OPTION>N\n");
  673.             }
  674.            else
  675.             {
  676.             fprintf(cgiOut,"<OPTION>N\n");
  677.             /* fprintf(cgiOut,"<OPTION>Y\n"); */
  678.             }
  679.             fprintf(cgiOut,"</SELECT>\n");
  680.         fprintf(cgiOut,"</TD>\n");
  681.         fprintf(cgiOut,"</TR>\n");
  682.         }
  683.       fprintf(cgiOut,"</TABLE>\n");
  684.       fprintf(cgiOut,"*Note: Length will be ignored for INTs and REALs.<BR><BR>\n",numfields);
  685.       fprintf(cgiOut,"<INPUT TYPE=SUBMIT VALUE=\"Add this table definition...\">\n");
  686.       fprintf(cgiOut,"</FORM></CENTER>\n");
  687.       }
  688.      else
  689.       {
  690.       fprintf(cgiOut,"ERROR: Invalid number if fields chosen!<BR>\n");
  691.       fprintf(cgiOut,"Please submit an integer x where 0 < x < %d<BR>\n",MAX_FIELDS);
  692.       msqlClose(sock);
  693.       giveButtonBar();
  694.       exit(1);
  695.       }
  696.   msqlClose(sock);
  697. }
  698.  
  699.  
  700. /* -------------------------- ADD TABLE NOW ------------------------------- */
  701. /*                               STATE = 7                                  */
  702. void addTableNow(void)
  703. {
  704. int x;
  705.  
  706.   giveTitle();
  707.   connectMSQL();
  708.   connectDB();
  709.   connectTable();
  710.  
  711.   cgiFormInteger("numfields",&numfields,0);
  712.   getFields();
  713.   #ifdef DEBUG
  714.   fprintf(cgiOut,"NUMBER OF FIELDS = %d<BR>\n",numfields);
  715.   fprintf(cgiOut,"CREATE TABLE %s (<BR>\n",thetable);
  716.   for(x=1; x<=numfields; x++)
  717.     {
  718.     fprintf(cgiOut,"%s %s",&field[x-1][0],&type[x-1][0]); 
  719.     if (strcmp(&type[x-1][0],"CHAR")==0) { fprintf(cgiOut,"(%s)",&lengthStr[x-1][0]); }
  720.     if (strcmp(¬nul[x-1][0],"Y")==0) { fprintf(cgiOut," not null"); }
  721.     if (strcmp(&key[x-1][0],"Y")==0) { fprintf(cgiOut," primary key"); }
  722.     if (x!=numfields) { fprintf(cgiOut,",<BR>\n"); }
  723.      else { fprintf(cgiOut," )<BR>\n"); }
  724.     }
  725.   #endif
  726.   strcpy(qbuf,"CREATE TABLE ");
  727.   strcat(qbuf,thetable);
  728.   strcat(qbuf," ( ");
  729.   for(x=1; x<=numfields; x++)
  730.     {
  731.     strcat(qbuf,&field[x-1][0]);
  732.     strcat(qbuf," ");
  733.     strcat(qbuf,&type[x-1][0]);
  734.     if (strcmp(&type[x-1][0],"CHAR")==0)
  735.       {
  736.       strcat(qbuf,"(");
  737.       strcat(qbuf,&lengthStr[x-1][0]);
  738.       strcat(qbuf,")");
  739.       }
  740.     if (strcmp(¬nul[x-1][0],"Y")==0) { strcat(qbuf," not null"); }
  741.     if (strcmp(&key[x-1][0],"Y")==0) { strcat(qbuf," primary key"); }
  742.     if (x!=numfields) { strcat(qbuf,", "); }
  743.      else { strcat(qbuf," )"); }
  744.     }
  745. #ifdef DEBUG
  746.   fprintf(cgiOut,"<BR>query = %s",qbuf);
  747. #endif
  748.  
  749.   if (msqlQuery(sock,qbuf) == -1)
  750.     {
  751.    fprintf(cgiOut,"ERROR: unable to add table %s to %s.<BR>\n",thetable,thedb);
  752.     fprintf(cgiOut,"Invalid query = %s<BR>\n",qbuf);
  753.     msqlClose(sock);
  754.       giveButtonBar();
  755.     exit(1);
  756.     }
  757.   fprintf(cgiOut,"Table %s added.\n",thetable);
  758.   showCurrentTables();
  759.   giveAddTable();
  760.   msqlClose(sock);
  761. }
  762.  
  763. void getFields(void)
  764. {
  765.   cgiFormString("field1",&field[0][0],MAX_FIELDNAME_LEN);
  766.   cgiFormString("field2",&field[1][0],MAX_FIELDNAME_LEN);
  767.   cgiFormString("field3",&field[2][0],MAX_FIELDNAME_LEN);
  768.   cgiFormString("field4",&field[3][0],MAX_FIELDNAME_LEN);
  769.   cgiFormString("field5",&field[4][0],MAX_FIELDNAME_LEN);
  770.   cgiFormString("field6",&field[5][0],MAX_FIELDNAME_LEN);
  771.   cgiFormString("field7",&field[6][0],MAX_FIELDNAME_LEN);
  772.   cgiFormString("field8",&field[7][0],MAX_FIELDNAME_LEN);
  773.   cgiFormString("field9",&field[8][0],MAX_FIELDNAME_LEN);
  774.   cgiFormString("field10",&field[9][0],MAX_FIELDNAME_LEN);
  775.   cgiFormString("field11",&field[10][0],MAX_FIELDNAME_LEN);
  776.   cgiFormString("field12",&field[11][0],MAX_FIELDNAME_LEN);
  777.   cgiFormString("field13",&field[12][0],MAX_FIELDNAME_LEN);
  778.   cgiFormString("field14",&field[13][0],MAX_FIELDNAME_LEN);
  779.   cgiFormString("field15",&field[14][0],MAX_FIELDNAME_LEN);
  780.   cgiFormString("field16",&field[15][0],MAX_FIELDNAME_LEN);
  781.   cgiFormString("field17",&field[16][0],MAX_FIELDNAME_LEN);
  782.   cgiFormString("field18",&field[17][0],MAX_FIELDNAME_LEN);
  783.   cgiFormString("field19",&field[18][0],MAX_FIELDNAME_LEN);
  784.   cgiFormString("field20",&field[19][0],MAX_FIELDNAME_LEN);
  785.   cgiFormString("field21",&field[20][0],MAX_FIELDNAME_LEN);
  786.   cgiFormString("field22",&field[21][0],MAX_FIELDNAME_LEN);
  787.   cgiFormString("field23",&field[22][0],MAX_FIELDNAME_LEN);
  788.   cgiFormString("field24",&field[23][0],MAX_FIELDNAME_LEN);
  789.   cgiFormString("field25",&field[24][0],MAX_FIELDNAME_LEN);
  790.  
  791.   cgiFormString("type1",&type[0][0],5);
  792.   cgiFormString("type2",&type[1][0],5);
  793.   cgiFormString("type3",&type[2][0],5);
  794.   cgiFormString("type4",&type[3][0],5);
  795.   cgiFormString("type5",&type[4][0],5);
  796.   cgiFormString("type6",&type[5][0],5);
  797.   cgiFormString("type7",&type[6][0],5);
  798.   cgiFormString("type8",&type[7][0],5);
  799.   cgiFormString("type9",&type[8][0],5);
  800.   cgiFormString("type10",&type[9][0],5);
  801.   cgiFormString("type11",&type[10][0],5);
  802.   cgiFormString("type12",&type[11][0],5);
  803.   cgiFormString("type13",&type[12][0],5);
  804.   cgiFormString("type14",&type[13][0],5);
  805.   cgiFormString("type15",&type[14][0],5);
  806.   cgiFormString("type16",&type[15][0],5);
  807.   cgiFormString("type17",&type[16][0],5);
  808.   cgiFormString("type18",&type[17][0],5);
  809.   cgiFormString("type19",&type[18][0],5);
  810.   cgiFormString("type20",&type[19][0],5);
  811.   cgiFormString("type21",&type[20][0],5);
  812.   cgiFormString("type22",&type[21][0],5);
  813.   cgiFormString("type23",&type[22][0],5);
  814.   cgiFormString("type24",&type[23][0],5);
  815.   cgiFormString("type25",&type[24][0],5);
  816.  
  817.   cgiFormString("lengthStr1",&lengthStr[0][0],0);
  818.   cgiFormString("lengthStr2",&lengthStr[1][0],0);
  819.   cgiFormString("lengthStr3",&lengthStr[2][0],0);
  820.   cgiFormString("lengthStr4",&lengthStr[3][0],0);
  821.   cgiFormString("lengthStr5",&lengthStr[4][0],0);
  822.   cgiFormString("lengthStr6",&lengthStr[5][0],0);
  823.   cgiFormString("lengthStr7",&lengthStr[6][0],0);
  824.   cgiFormString("lengthStr8",&lengthStr[7][0],0);
  825.   cgiFormString("lengthStr9",&lengthStr[8][0],0);
  826.   cgiFormString("lengthStr10",&lengthStr[9][0],0);
  827.   cgiFormString("lengthStr11",&lengthStr[10][0],0);
  828.   cgiFormString("lengthStr12",&lengthStr[11][0],0);
  829.   cgiFormString("lengthStr13",&lengthStr[12][0],0);
  830.   cgiFormString("lengthStr14",&lengthStr[13][0],0);
  831.   cgiFormString("lengthStr15",&lengthStr[14][0],0);
  832.   cgiFormString("lengthStr16",&lengthStr[15][0],0);
  833.   cgiFormString("lengthStr17",&lengthStr[16][0],0);
  834.   cgiFormString("lengthStr18",&lengthStr[17][0],0);
  835.   cgiFormString("lengthStr19",&lengthStr[18][0],0);
  836.   cgiFormString("lengthStr20",&lengthStr[19][0],0);
  837.   cgiFormString("lengthStr21",&lengthStr[20][0],0);
  838.   cgiFormString("lengthStr22",&lengthStr[21][0],0);
  839.   cgiFormString("lengthStr23",&lengthStr[22][0],0);
  840.   cgiFormString("lengthStr24",&lengthStr[23][0],0);
  841.   cgiFormString("lengthStr25",&lengthStr[24][0],0);
  842.  
  843.   cgiFormString("notnul1",¬nul[0][0],2);
  844.   cgiFormString("notnul2",¬nul[1][0],2);
  845.   cgiFormString("notnul3",¬nul[2][0],2);
  846.   cgiFormString("notnul4",¬nul[3][0],2);
  847.   cgiFormString("notnul5",¬nul[4][0],2);
  848.   cgiFormString("notnul6",¬nul[5][0],2);
  849.   cgiFormString("notnul7",¬nul[6][0],2);
  850.   cgiFormString("notnul8",¬nul[7][0],2);
  851.   cgiFormString("notnul9",¬nul[8][0],2);
  852.   cgiFormString("notnul10",¬nul[9][0],2);
  853.   cgiFormString("notnul11",¬nul[10][0],2);
  854.   cgiFormString("notnul12",¬nul[11][0],2);
  855.   cgiFormString("notnul13",¬nul[12][0],2);
  856.   cgiFormString("notnul14",¬nul[13][0],2);
  857.   cgiFormString("notnul15",¬nul[14][0],2);
  858.   cgiFormString("notnul16",¬nul[15][0],2);
  859.   cgiFormString("notnul17",¬nul[16][0],2);
  860.   cgiFormString("notnul18",¬nul[17][0],2);
  861.   cgiFormString("notnul19",¬nul[18][0],2);
  862.   cgiFormString("notnul20",¬nul[19][0],2);
  863.   cgiFormString("notnul21",¬nul[20][0],2);
  864.   cgiFormString("notnul22",¬nul[21][0],2);
  865.   cgiFormString("notnul23",¬nul[22][0],2);
  866.   cgiFormString("notnul24",¬nul[23][0],2);
  867.   cgiFormString("notnul25",¬nul[24][0],2);
  868.  
  869.   cgiFormString("key1",&key[0][0],2);
  870.   cgiFormString("key2",&key[1][0],2);
  871.   cgiFormString("key3",&key[2][0],2);
  872.   cgiFormString("key4",&key[3][0],2);
  873.   cgiFormString("key5",&key[4][0],2);
  874.   cgiFormString("key6",&key[5][0],2);
  875.   cgiFormString("key7",&key[6][0],2);
  876.   cgiFormString("key8",&key[7][0],2);
  877.   cgiFormString("key9",&key[8][0],2);
  878.   cgiFormString("key10",&key[9][0],2);
  879.   cgiFormString("key11",&key[10][0],2);
  880.   cgiFormString("key12",&key[11][0],2);
  881.   cgiFormString("key13",&key[12][0],2);
  882.   cgiFormString("key14",&key[13][0],2);
  883.   cgiFormString("key15",&key[14][0],2);
  884.   cgiFormString("key16",&key[15][0],2);
  885.   cgiFormString("key17",&key[16][0],2);
  886.   cgiFormString("key18",&key[17][0],2);
  887.   cgiFormString("key19",&key[18][0],2);
  888.   cgiFormString("key20",&key[19][0],2);
  889.   cgiFormString("key21",&key[20][0],2);
  890.   cgiFormString("key22",&key[21][0],2);
  891.   cgiFormString("key23",&key[22][0],2);
  892.   cgiFormString("key24",&key[23][0],2);
  893.   cgiFormString("key25",&key[24][0],2);
  894. }
  895.  
  896.  
  897. /* -------------------------- CHOOSE TABLE PAGE --------------------------- */
  898. /*                               STATE = 8                                 */
  899.  
  900. void doTableSelection(void)
  901. {
  902.   giveTitle();
  903.   connectMSQL();
  904.   connectDB();
  905.   giveSearch(); 
  906.   giveInsert();
  907.   giveTextQuery();
  908.   msqlClose(sock);
  909. }
  910.  
  911. void giveSearch(void)
  912. {
  913.   fprintf(cgiOut,"<H3>Search a table (update/delete)...</H3>\n");
  914.   fprintf(cgiOut,"<FORM METHOD=POST ACTION=%s/dbadmin>\n",RELPATH);
  915.   fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=state VALUE=12>\n");
  916.   showTables();
  917.   fprintf(cgiOut,"<INPUT TYPE=SUBMIT VALUE=\"Perform Search...\">\n");
  918.   fprintf(cgiOut,"</FORM><HR>");
  919. }
  920.  
  921. void giveInsert(void)
  922. {
  923.   fprintf(cgiOut,"<H3>Add data to a table...</H3>\n");
  924.   fprintf(cgiOut,"<FORM METHOD=POST ACTION=%s/dbadmin>\n",RELPATH);
  925.   fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=state VALUE=10>\n");
  926.   showTables();
  927.   fprintf(cgiOut,"<INPUT TYPE=SUBMIT VALUE=\"Begin Insert...\">\n");
  928.   fprintf(cgiOut,"</FORM><HR>");
  929. }
  930.  
  931. void showTables(void)
  932. {
  933. int x=0;
  934.   res = msqlListTables(sock);
  935.   if (!res)
  936.     {
  937.    fprintf(cgiOut,"\nERROR : Unable to list tables in database %s<BR>\n",thedb);
  938.     msqlClose(sock);
  939.       giveButtonBar();
  940.     exit(1);
  941.     }
  942.   while(cur = msqlFetchRow(res))
  943.     { 
  944.     x++;
  945.     fprintf(cgiOut,"<DD><INPUT TYPE=RADIO NAME=\"thetable\" VALUE=\"%s\" ",cur[0]);
  946.     if (x==1) { fprintf(cgiOut," CHECKED"); }
  947.     fprintf(cgiOut,"> %s\n<BR>",cur[0]);
  948.     }
  949.   fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"thedb\" VALUE=\"%s\">\n",thedb);
  950. /*  fprintf(cgiOut,"<INPUT TYPE=SUBMIT VALUE=\"New Record... \">\n"); */
  951. /*  fprintf(cgiOut,"</FORM><HR>\n"); */
  952. }
  953.  
  954. void giveCannedSelect(void)
  955. {
  956.   fprintf(cgiOut,"<H3>Select a query:</H3>\n");
  957.   fprintf(cgiOut,"<FORM METHOD=POST ACTION=%s/dbadmin>",RELPATH);
  958.   fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"state\" VALUE=xx>\n");
  959.   fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"thedb\" VALUE=\"%s\">\n",thedb);
  960.   fprintf(cgiOut,"SELECT...<BR>\n");
  961.   fprintf(cgiOut,"<DD><INPUT TYPE=CHECKBOX NAME=\"columns\"> * <BR>\n");
  962.   fprintf(cgiOut,"FROM...<BR>\n");
  963.   res = msqlListTables(sock);
  964.   while((cur = msqlFetchRow(res)))
  965.     { fprintf(cgiOut,"<DD><INPUT TYPE=CHECKBOX NAME=\"thetable\" VALUE=\"%s\"> %s\n<BR>",cur[0],cur[0]); }
  966.   fprintf(cgiOut,"</FORM>\n");
  967.   fprintf(cgiOut,"<HR>\n");
  968. }
  969.  
  970. void giveTextQuery(void)
  971. {
  972.   fprintf(cgiOut,"<H3>Enter a mSQL query by hand if you prefer:</H3>\n");
  973.   fprintf(cgiOut,"<FORM METHOD=POST ACTION=%s/dbadmin>",RELPATH);
  974.   fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"state\" VALUE=9>\n");
  975.   fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"thedb\" VALUE=\"%s\">\n",thedb);
  976.   fprintf(cgiOut,"<TEXTAREA COLS=60 ROWS=10 NAME=\"textquery\">\n");
  977.   fprintf(cgiOut,"SELECT * FROM (table_name)\n");
  978.   fprintf(cgiOut,"</TEXTAREA>\n");
  979.   fprintf(cgiOut,"<INPUT TYPE=SUBMIT VALUE=\"Submit mSQL query...\">\n");
  980.   fprintf(cgiOut,"</FORM>\n");
  981. }
  982.  
  983.  
  984. /* --------------------------- DO TEXT QUERY ----------------------------- */
  985. /*                               STATE = 9                                 */
  986.  
  987. void doTextQuery(void)
  988. {
  989. int  query_len;
  990. char *thetextquery;
  991. char *command;
  992.  
  993. /* xxx */
  994.  
  995.   giveTitle();
  996.   connectMSQL();
  997.   connectDB();
  998.  
  999.   cgiFormStringSpaceNeeded("textquery",&query_len);
  1000.   thetextquery=(char *)malloc(sizeof(char)*query_len);
  1001.   cgiFormString("textquery",thetextquery,query_len);
  1002.  
  1003.   if (msqlQuery(sock,thetextquery) == -1)
  1004.     {
  1005.     fprintf(cgiOut,"ERROR: unable to perform query on database %s.<BR>\n",thedb);
  1006.     fprintf(cgiOut,"Invalid query = %s<BR>\n",thetextquery);
  1007.     msqlClose(sock);
  1008.     giveBackQueryPage();
  1009.     giveButtonBar();
  1010.     exit(1);
  1011.     }
  1012.  
  1013.   command = strtok(thetextquery," ");
  1014.   if ((strcmp(command,"SELECT")==0) || (strcmp(command,"select")==0))
  1015.     { 
  1016.     fprintf(cgiOut,"<CENTER>The query \"%s\" returned the following values:\n",thetextquery);
  1017.     showSelectData();
  1018.     }
  1019.   fprintf(cgiOut,"<BR>Query request completed.<BR>\n");
  1020.   giveBackQueryPage(); 
  1021.   free(thetextquery);
  1022.   msqlClose(sock);
  1023. }
  1024.  
  1025. void showSelectData(void)
  1026. {
  1027. int cols,rows,x,y;
  1028.  
  1029.   res=msqlStoreResult();
  1030.   fprintf(cgiOut,"<TABLE BORDER=4 CELLPADDING=2>\n");
  1031.   rows=msqlNumRows(res);
  1032.   cols=msqlNumFields(res);
  1033.   for (x=0; x<rows; x++)
  1034.     { 
  1035.     fprintf(cgiOut,"<TR>\n");
  1036.     cur=msqlFetchRow(res);
  1037.     for (y=0; y<cols; y++)
  1038.       {
  1039.       fprintf(cgiOut,"<TD NOWRAP>\n");
  1040.       fprintf(cgiOut,"%s\n",cur[y]);
  1041.       fprintf(cgiOut,"</TD>\n");
  1042.       }
  1043.     fprintf(cgiOut,"</TR>\n");
  1044.     }
  1045.   fprintf(cgiOut,"</TABLE>\n");
  1046.   msqlFreeResult(res);
  1047. }
  1048.  
  1049.  
  1050. /* -------------------------- CANNED QUERY PAGE -------------------------- */
  1051. /*                               STATE = 10                                */
  1052.  
  1053. void doCannedQuery(void)
  1054. {
  1055. int size=1;
  1056.  
  1057.   giveTitle();
  1058.   connectMSQL();
  1059.   connectDB();
  1060.   connectTable();
  1061.  
  1062.   giveInsertForm();
  1063.   msqlClose(sock);
  1064. }
  1065.  
  1066. void giveInsertForm(void)
  1067. {
  1068. int size=1;
  1069.   fieldnames = (char *)malloc(1*sizeof(char));
  1070.   strcpy(fieldnames,"");
  1071.   res=msqlListFields(sock,thetable);
  1072.   if (!res)
  1073.     {
  1074.     fprintf(cgiOut,"ERROR : Couldn't find %s in %s!<BR>\n",thetable,thedb);
  1075.     msqlFreeResult(res);
  1076.       giveButtonBar();
  1077.     exit(1);
  1078.     }
  1079.    else
  1080.     {
  1081.     fprintf(cgiOut,"<H3>Add new data to table %s:</H3>\n",thetable);
  1082.     fprintf(cgiOut,"<CENTER>\n");
  1083.     fprintf(cgiOut,"<FORM METHOD=POST ACTION=%s/dbadmin>\n",RELPATH);
  1084.     fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"state\" VALUE=11>\n");
  1085.     fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"thedb\" VALUE=\"%s\">\n",thedb);
  1086.     fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"thetable\" VALUE=\"%s\">\n",thetable);
  1087.     fprintf(cgiOut,"<TABLE WIDTH=75%% BORDER=2 CELLPADDING=4>\n");
  1088.     while((curField = msqlFetchField(res)))
  1089.       {
  1090.       size = size + strlen(curField->name) + 2;
  1091.       fieldnames= (char *)realloc((void *)fieldnames,size);
  1092.       strcat(fieldnames,curField->name);
  1093.       strcat(fieldnames,",");
  1094.       fprintf(cgiOut,"<TR><TH>%s</TH>\n",curField->name);
  1095.       fprintf(cgiOut,"<TD>"); 
  1096.       if (curField->type==INT_TYPE) { fprintf(cgiOut,"INT"); }
  1097.       if (curField->type==CHAR_TYPE) { fprintf(cgiOut,"CHAR[%d]",curField->length);}
  1098.       if (curField->type==REAL_TYPE) { fprintf(cgiOut,"REAL"); }
  1099.       fprintf(cgiOut,"%s", IS_NOT_NULL(curField->flags)? "(NOT NULL)":"");
  1100.       fprintf(cgiOut,"</TD>");
  1101.       fprintf(cgiOut,"<TD ALIGN=CENTER><INPUT TYPE=\"TEXT\" NAME=\"%s\" SIZE=25></TD></TR>\n",curField->name);
  1102.       }
  1103.     fprintf(cgiOut,"</TABLE>\n");
  1104.     fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"fieldnames\" VALUE=\"%s\">\n",fieldnames); 
  1105.     fprintf(cgiOut,"<INPUT TYPE=SUBMIT VALUE=\"Add entry to table...\">\n");
  1106.     fprintf(cgiOut,"</FORM>\n");
  1107.     fprintf(cgiOut,"</CENTER>\n");
  1108.     free(fieldnames);
  1109. #ifdef DEBUG
  1110.     fprintf(cgiOut,"SIZE=%d\n"),size;
  1111. #endif
  1112.     }
  1113.   giveBackQueryPage(); 
  1114. }
  1115.  
  1116. void giveBackQueryPage(void)
  1117. {
  1118.   fprintf(cgiOut,"<CENTER><HR>\n");
  1119.   fprintf(cgiOut,"<FORM METHOD=POST ACTION=%s/dbadmin>\n",RELPATH);
  1120.   fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"state\" VALUE=8>\n");
  1121.   fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"thedb\" VALUE=\"%s\">\n",thedb);
  1122.   fprintf(cgiOut,"<INPUT TYPE=SUBMIT VALUE=\"RETURN TO MAIN QUERY PAGE\">\n");
  1123.   fprintf(cgiOut,"</FORM>\n");
  1124.   fprintf(cgiOut,"<HR></CENTER>\n");
  1125. }
  1126.  
  1127. /* -------------------------- ADD CANNED QUERY  -------------------------- */
  1128. /*                               STATE = 11                                */
  1129.  
  1130. void addCannedQuery(void)
  1131. {
  1132. int count=0;
  1133. int x,lengthstr;
  1134. char *the_data;
  1135.  
  1136.   giveTitle();
  1137.  
  1138.   connectMSQL();
  1139.   connectDB();
  1140.   connectTable();
  1141.  
  1142.   res=msqlListFields(sock,thetable);
  1143.   if (res == NULL)
  1144.     {
  1145.     fprintf(cgiOut,"ERROR : Couldn't find %s in %s!<BR>\n",thetable,thedb);
  1146.     msqlFreeResult(res);
  1147.       giveButtonBar();
  1148.     exit(1);
  1149.     }
  1150.   strcpy(qbuf,"INSERT INTO ");
  1151.   strcat(qbuf,thetable);
  1152.   strcat(qbuf," ( ");
  1153.   while((curField = msqlFetchField(res)))
  1154.     {
  1155.     if (count>0) {strcat(qbuf,", ");}
  1156.     count++;
  1157.     strcat(qbuf,curField->name);
  1158.     }
  1159.   strcat(qbuf," ) VALUES ( ");
  1160.  
  1161.   msqlFreeResult(res);
  1162.   res=msqlListFields(sock,thetable);
  1163.   count=0;
  1164.   while(curField = msqlFetchField(res))
  1165.     {
  1166.     cgiFormStringSpaceNeeded(curField->name,&lengthstr);
  1167.     the_data = (char *)malloc(sizeof(char)*lengthstr);
  1168.     cgiFormString(curField->name,the_data,lengthstr);
  1169.  
  1170.     if (count>0) {strcat(qbuf,", ");}
  1171.     count++;
  1172.     switch (curField->type)
  1173.       {
  1174.       case INT_TYPE:
  1175.       case REAL_TYPE:
  1176.                      if (lengthstr > 1)
  1177.                        { strcat(qbuf,the_data); }
  1178.                       else
  1179.                        { strcat(qbuf,"NULL"); }
  1180.                      break;
  1181.       case CHAR_TYPE:
  1182.                      if (lengthstr > 1)
  1183.                        { 
  1184.                        strcat(qbuf,"'");
  1185.                        strcat(qbuf,the_data);
  1186.                        strcat(qbuf,"'");
  1187.                        }
  1188.                       else                       
  1189.                        { strcat(qbuf,"NULL"); }
  1190.                      break;
  1191.       default:
  1192.                      fprintf(cgiOut,"Error: Unknown mSQL field type");
  1193.                      giveButtonBar();
  1194.                      exit(1);
  1195.                      break;
  1196.       }
  1197.     free(the_data);
  1198.     }
  1199.   strcat(qbuf,")");
  1200.   #ifdef DEBUG
  1201.   fprintf(cgiOut,"Query = %s<BR>\n",qbuf);
  1202.   #endif
  1203.  
  1204.   
  1205.   if (msqlQuery(sock,qbuf) == -1)
  1206.     {
  1207.    fprintf(cgiOut,"ERROR: unable to perform query on database %s.<BR>\n",thedb);
  1208.     fprintf(cgiOut,"Invalid query = %s<BR>\n",qbuf);
  1209.     giveInsertForm();
  1210.     msqlClose(sock);
  1211.     giveButtonBar();
  1212.     exit(1);
  1213.     }
  1214.  
  1215.   msqlFreeResult(res);
  1216.   fprintf(cgiOut,"Insert completed.\n"); 
  1217.  
  1218.    giveInsertForm(); 
  1219.  
  1220.    msqlClose(sock); 
  1221.  
  1222.  
  1223. /* --------------------------- SEARCH RECORD ----------------------------- */
  1224. /*                               STATE = 12                                */
  1225.  
  1226. void searchRecords(void)
  1227. {
  1228.   giveTitle();
  1229.   connectMSQL();
  1230.   connectDB();
  1231.   connectTable();
  1232.  
  1233.   giveSearchForm();
  1234.   giveBackQueryPage();
  1235.   msqlClose(sock);
  1236. }
  1237.  
  1238. void giveSearchForm(void)
  1239. {
  1240.   fprintf(cgiOut,"<H3>Search of table %s:</H3>\n",thetable);
  1241.   fprintf(cgiOut,"<CENTER>\n");
  1242.   fprintf(cgiOut,"<FORM METHOD=POST ACTION=%s/dbadmin>\n",RELPATH);
  1243.   fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"thedb\" VALUE=\"%s\">\n",thedb);
  1244.   fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"thetable\" VALUE=%s>\n",thetable);
  1245.   fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"state\" VALUE=14>\n");
  1246.   fprintf(cgiOut,"<TABLE WIDTH=75%% BORDER=2 CELLPADDING=4>\n");
  1247.   res = msqlListFields(sock,thetable);
  1248.   while (curField = msqlFetchField(res))
  1249.     {
  1250.     fprintf(cgiOut,"<TR>");
  1251.     fprintf(cgiOut,"<TH ALIGN=CENTER>%s</TH>",curField->name);
  1252.     fprintf(cgiOut,"<TD>");
  1253.       if (curField->type==INT_TYPE) { fprintf(cgiOut,"INT"); }
  1254.       if (curField->type==CHAR_TYPE) { fprintf(cgiOut,"CHAR[%d]",curField->length);}
  1255.       if (curField->type==REAL_TYPE) { fprintf(cgiOut,"REAL"); }
  1256.     fprintf(cgiOut,"</TD>\n");
  1257.     fprintf(cgiOut,"<TD><SELECT NAME=\"%s_operation\"><OPTION>LIKE\n",curField->name);
  1258.     fprintf(cgiOut,"<OPTION><\n");
  1259.     fprintf(cgiOut,"<OPTION>=\n");
  1260.     fprintf(cgiOut,"<OPTION>>\n");
  1261.     fprintf(cgiOut,"</SELECT></TD>\n");
  1262.     fprintf(cgiOut,"<TD ALIGN=CENTER><INPUT NAME=\"%s\" SIZE=25></TD></TR>\n",curField->name);
  1263.     }
  1264.   fprintf(cgiOut,"</TABLE>\n");
  1265.   fprintf(cgiOut,"ORDER BY:\n");
  1266.   fprintf(cgiOut,"<SELECT NAME=\"order\">\n");
  1267.   msqlFreeResult(res);
  1268.   res = msqlListFields(sock,thetable);
  1269.   while (curField = msqlFetchField(res))
  1270.     {
  1271.     fprintf(cgiOut,"<OPTION> %s\n",curField->name);
  1272.     }
  1273.   fprintf(cgiOut,"</SELECT>\n");
  1274.   fprintf(cgiOut,"OPTION FOR:\n");
  1275.   fprintf(cgiOut,"<SELECT NAME=\"action\"><OPTION> UPDATE\n<OPTION> DELETE\n</SELECT>\n");
  1276.   fprintf(cgiOut,"<INPUT TYPE=SUBMIT VALUE=\"PERFORM SEARCH...\">\n");
  1277.   fprintf(cgiOut,"</FORM></CENTER>\n");
  1278.   msqlFreeResult(res);
  1279. }
  1280.  
  1281.  
  1282. /* --------------------------- RETURN SEARCH  ----------------------------- */
  1283. /*                               STATE = 14                                */
  1284.  
  1285. void returnSearch(void)
  1286. {
  1287.   giveTitle();
  1288.   connectMSQL();
  1289.   connectDB();
  1290.   connectTable();
  1291.   getSearchSpec();
  1292.   doSearchQuery();
  1293.   giveSearchForm();
  1294.   giveBackQueryPage();
  1295.   msqlClose(sock);
  1296. }
  1297.  
  1298. void getSearchSpec(void)
  1299. {
  1300. int count;
  1301. int  op_temp_len;
  1302. char *op_temp;         /* (field_name)_operation\0 */
  1303. int  operation_len;
  1304. char *operation;
  1305. int  pattern_len;
  1306. char *pattern;
  1307. int  order_len;
  1308. char *order;
  1309. int  action_len;
  1310. char *action;
  1311.  
  1312.   count=0;
  1313.   pattern_len=0;
  1314.   strcpy(qbuf,"SELECT * FROM ");
  1315.   strcat(qbuf,thetable);
  1316.   strcat(qbuf," WHERE ");
  1317.   res = msqlListFields(sock,thetable);
  1318.   while (curField = msqlFetchField(res))
  1319.     {
  1320.     op_temp_len = strlen(curField->name) + 11; 
  1321.     op_temp = (char *)malloc(sizeof(char)*op_temp_len);
  1322.     strcpy(op_temp,curField->name);
  1323.     strcat(op_temp,"_operation");
  1324.  
  1325.     cgiError=cgiFormStringSpaceNeeded(op_temp,&operation_len);
  1326.     operation=(char *)malloc(sizeof(char)*operation_len);
  1327.     cgiError=cgiFormString(op_temp,operation,operation_len);
  1328.  
  1329.     cgiError=cgiFormStringSpaceNeeded(curField->name,&pattern_len);
  1330.     if (pattern_len > 1) 
  1331.       {
  1332.       count++;
  1333.       pattern=(char *)malloc(sizeof(char)*pattern_len);
  1334.       cgiFormString(curField->name,pattern,pattern_len);
  1335.       if (count>1) { strcat(qbuf," AND "); }
  1336.       strcat(qbuf,curField->name);
  1337.       strcat(qbuf," ");
  1338.       strcat(qbuf,operation);
  1339.       strcat(qbuf," ");
  1340.       if (curField->type == CHAR_TYPE) { strcat(qbuf,"'"); }
  1341.       strcat(qbuf,pattern);
  1342.       if (curField->type == CHAR_TYPE) { strcat(qbuf,"'"); }
  1343.       free(pattern);
  1344.       }
  1345.     free(operation);
  1346.     free(op_temp);
  1347.     }
  1348.   cgiError=cgiFormStringSpaceNeeded("order",&order_len);
  1349.   order=(char *)malloc(sizeof(char)*order_len);
  1350.   cgiError=cgiFormString("order",order,order_len);
  1351.   strcat(qbuf," ORDER BY ");
  1352.   strcat(qbuf,order);
  1353.   free(order);
  1354. }
  1355.  
  1356. void doSearchQuery(void)
  1357. {
  1358. #ifdef DEBUG
  1359.   fprintf(cgiOut,"Query = %s\n",qbuf);
  1360. #endif
  1361.   if (msqlQuery(sock,qbuf) == -1)
  1362.     {
  1363.     fprintf(cgiOut,"ERROR: unable to perform query on database %s.<BR>\n",thedb);
  1364.     fprintf(cgiOut,"Invalid query = %s<BR>\n",qbuf);
  1365.     msqlClose(sock);
  1366.     giveButtonBar();
  1367.     exit(1);
  1368.     }
  1369.   showSelectDeleteData(); 
  1370. }
  1371.  
  1372. void showSelectDeleteData(void)
  1373. {
  1374. int cols,rows,x,y,z;
  1375. int  action_len;
  1376. char *action;
  1377. int  rec_id_len;
  1378. char *rec_id;
  1379.  
  1380.   cgiError=cgiFormStringSpaceNeeded("action",&action_len);
  1381.   action=(char *)malloc(sizeof(char)*action_len);
  1382.   cgiError=cgiFormString("action",action,action_len);
  1383.  
  1384.   res=msqlStoreResult();
  1385.   fprintf(cgiOut,"<CENTER>\n");
  1386.   rows=msqlNumRows(res);
  1387.   cols=msqlNumFields(res);
  1388.   fprintf(cgiOut,"%d rows were returned by your search:<BR>\n",rows);
  1389.   z=0;
  1390.   for (x=0; x<rows; x++)
  1391.     {
  1392.     cur=msqlFetchRow(res);
  1393.     res2 = msqlListFields(sock,thetable);
  1394.     rec_id = (char *)malloc(sizeof(char));
  1395.     strcpy(rec_id,"");
  1396.     rec_id_len = 1;
  1397.     z=0;
  1398.     while (curField = msqlFetchField(res2))
  1399.       {
  1400.       if (z > 0)
  1401.         {
  1402.         rec_id_len += 5;
  1403.         rec_id=(char *)realloc(rec_id,rec_id_len);
  1404.         strcat(rec_id," AND ");
  1405.         }
  1406.       rec_id_len += strlen(curField->name);
  1407.       rec_id_len += 3;
  1408.       rec_id=(char *)realloc(rec_id,rec_id_len);
  1409.       strcat(rec_id,curField->name);
  1410.       strcat(rec_id," = ");
  1411.       if (curField->type==CHAR_TYPE)
  1412.         {
  1413.         if (cur[z] != NULL)
  1414.           {
  1415.           rec_id_len += 1;
  1416.           rec_id=(char *)realloc(rec_id,rec_id_len);
  1417.           strcat(rec_id,"'");
  1418.           }
  1419.         }
  1420. /* HERE */
  1421.       if (cur[z] == NULL)
  1422.         {
  1423.         rec_id_len += 4;
  1424.         rec_id=(char *)realloc(rec_id,rec_id_len);
  1425.         strcat(rec_id,"NULL");
  1426.         }
  1427.        else
  1428.         {
  1429.       rec_id_len += strlen(cur[z]);
  1430.       rec_id=(char *)realloc(rec_id,rec_id_len);
  1431.       strcat(rec_id,cur[z]);
  1432.         }
  1433.       if (curField->type==CHAR_TYPE)
  1434.         {
  1435.         if (cur[z] != NULL)
  1436.           {
  1437.           rec_id_len += 1;
  1438.           rec_id=(char *)realloc(rec_id,rec_id_len);
  1439.           strcat(rec_id,"'");
  1440.           }
  1441.         }
  1442.       z++;
  1443.       }
  1444.     fprintf(cgiOut,"<FORM METHOD=POST ACTION=%s/dbadmin>\n",RELPATH);
  1445.     if (strcmp(action,"DELETE")==0)
  1446.       {
  1447.       fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"state\" VALUE=15>\n"); 
  1448.       fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"DELETE\">\n");
  1449.       }
  1450.     if (strcmp(action,"UPDATE")==0)
  1451.       {
  1452.       fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"state\" VALUE=16>\n"); 
  1453.       fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"action\" VALUE=\"UPDATE\">\n");
  1454.       }
  1455.     fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"thedb\" VALUE=\"%s\">\n",thedb);
  1456.     fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"thetable\" VALUE=\"%s\">\n",thetable);
  1457.     res2 = msqlListFields(sock,thetable);
  1458.     y=0;
  1459.     while (curField = msqlFetchField(res2))
  1460.       {
  1461.       fprintf(cgiOut,"<INPUT name=%s LENGTH=25 VALUE=\"%s\"> \n",curField->name,cur[y]);
  1462.       y++;
  1463.       }
  1464.     fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"record_query\" VALUE=\"%s\">\n",rec_id);
  1465.     fprintf(cgiOut,"<INPUT TYPE=HIDDEN NAME=\"total_query\" VALUE=\"%s\">\n",qbuf);
  1466.     if (strcmp(action,"DELETE")==0)
  1467.       { fprintf(cgiOut,"<INPUT TYPE=SUBMIT VALUE=\"DELETE RECORD\">\n"); }
  1468.     if (strcmp(action,"UPDATE")==0)
  1469.       { fprintf(cgiOut,"<INPUT TYPE=SUBMIT VALUE=\"UPDATE RECORD\">\n"); }
  1470.     fprintf(cgiOut,"</FORM>\n");
  1471.     /* fprintf(cgiOut,"<BR>\n"); */
  1472.     }
  1473. /*
  1474.   fprintf(cgiOut,"</CENTER><HR>\n");
  1475.   if (z>0) { free(rec_id); } 
  1476.   free(action);
  1477.   msqlFreeResult(res); 
  1478. */
  1479. }
  1480.  
  1481.  
  1482. /* ------------------------- DELETE SEARCH ITEM  ------------------------- */
  1483. /*                               STATE = 15                                */
  1484.  
  1485. void deleteSearchItem(void)
  1486. {
  1487.   giveTitle();
  1488.   connectMSQL();
  1489.   connectDB();
  1490.   connectTable();
  1491.   performDelete(); 
  1492.   giveBackOriginalQuery();
  1493.   giveBackQueryPage();
  1494.   msqlClose(sock);
  1495. }
  1496.  
  1497. void performDelete(void)
  1498. {
  1499. int rec_id_len;
  1500. char *rec_id;
  1501. int  query_len;
  1502. char *query;
  1503.  
  1504.   query_len = 13;
  1505.   query=(char *)malloc(sizeof(int)*query_len);
  1506.   strcpy(query,"DELETE FROM ");
  1507.   query_len += strlen(thetable);
  1508.   query=(char *)realloc(query,query_len);
  1509.   strcat(query,thetable);
  1510.   query_len += 7;
  1511.   query=(char *)realloc(query,query_len);
  1512.   strcat(query," WHERE ");
  1513.   cgiFormStringSpaceNeeded("record_query",&rec_id_len);
  1514.   rec_id=(char *)malloc(sizeof(char)*rec_id_len);
  1515.   cgiFormString("record_query",rec_id,rec_id_len);
  1516.   query_len += rec_id_len;
  1517.   query=(char *)realloc(query,query_len);
  1518.   strcat(query,rec_id);
  1519.   #ifdef DEBUG
  1520.   fprintf(cgiOut,"<BR>QUERY=%s\n<BR>\n",query);
  1521.   #endif
  1522.   msqlQuery(sock,query);
  1523.   free(query);
  1524.   free(rec_id);
  1525. }
  1526.  
  1527.  
  1528. /* ------------------------- UPDATE SEARCH ITEM  ------------------------- */
  1529. /*                               STATE = 16                                */
  1530.  
  1531. void updateSearchItem(void)
  1532. {
  1533.   giveTitle();
  1534.   connectMSQL();
  1535.   connectDB();
  1536.   connectTable();
  1537.   performUpdate(); 
  1538.   giveBackOriginalQuery();
  1539.   giveBackQueryPage();
  1540.   msqlClose(sock);
  1541. }
  1542.  
  1543. void performUpdate(void)
  1544. {
  1545. int rec_id_len;
  1546. char *rec_id;
  1547. int  query_len;
  1548. char *query;
  1549. int rec_new_len;
  1550. char *rec_new;
  1551. int z;
  1552. char *field_value;
  1553. int  field_value_len;
  1554.  
  1555.  
  1556.   query_len = 8;
  1557.   query=(char *)malloc(sizeof(int)*query_len);
  1558.   strcpy(query,"UPDATE ");
  1559.   query_len += strlen(thetable);
  1560.   query=(char *)realloc(query,query_len);
  1561.   strcat(query,thetable);
  1562.   query_len += 5;
  1563.   query=(char *)realloc(query,query_len);
  1564.   strcat(query," SET ");
  1565.  
  1566.     res2 = msqlListFields(sock,thetable);
  1567.     rec_new = (char *)malloc(sizeof(char));
  1568.     strcpy(rec_new,"");
  1569.     rec_new_len = 1;
  1570.     z=0;
  1571.     while (curField = msqlFetchField(res2))
  1572.       {
  1573.       if (z > 0)
  1574.         {
  1575.         rec_new_len += 2;
  1576.         rec_new=(char *)realloc(rec_new,rec_new_len);
  1577.         strcat(rec_new,", ");
  1578.         }
  1579.       rec_new_len += strlen(curField->name);
  1580.       rec_new_len += 3;
  1581.       rec_new=(char *)realloc(rec_new,rec_new_len);
  1582.       strcat(rec_new,curField->name);
  1583.       strcat(rec_new," = ");
  1584.  
  1585.       cgiFormStringSpaceNeeded(curField->name,&field_value_len);
  1586.       field_value=(char *)malloc(sizeof(char)*field_value_len);
  1587.       cgiFormString(curField->name,field_value,field_value_len);
  1588.       
  1589.       if (strcmp(field_value,"(null)")==0) 
  1590.         {
  1591.         rec_new_len += 4;
  1592.         rec_new=(char *)realloc(rec_new,rec_new_len);
  1593.         strcat(rec_new,"NULL");
  1594.         }
  1595.        else
  1596.         {      
  1597.         
  1598.  
  1599.         if (curField->type==CHAR_TYPE)
  1600.           {
  1601.           rec_new_len += 1;
  1602.           rec_new=(char *)realloc(rec_new,rec_new_len);
  1603.           strcat(rec_new,"'");
  1604.           }
  1605.  
  1606. /*
  1607.       cgiFormStringSpaceNeeded(curField->name,&field_value_len);
  1608.       field_value=(char *)malloc(sizeof(char)*field_value_len);
  1609.       cgiFormString(curField->name,field_value,field_value_len);
  1610. */ 
  1611.  
  1612.  
  1613.         rec_new_len += field_value_len;
  1614.         rec_new=(char *)realloc(rec_new,rec_new_len);
  1615.         strcat(rec_new,field_value);
  1616.         free(field_value);
  1617.       
  1618.         if (curField->type==CHAR_TYPE)
  1619.           {
  1620.           rec_new_len += 1;
  1621.           rec_new=(char *)realloc(rec_new,rec_new_len);
  1622.           strcat(rec_new,"'");
  1623.           }
  1624.         }
  1625.       z++;
  1626.       }
  1627.   query_len += strlen(rec_new);
  1628.   query=(char *)realloc(query,query_len);
  1629.   strcat(query,rec_new);
  1630.  
  1631.   query_len += 7;
  1632.   query=(char *)realloc(query,query_len);
  1633.   strcat(query," WHERE ");
  1634.   cgiFormStringSpaceNeeded("record_query",&rec_id_len);
  1635.   rec_id=(char *)malloc(sizeof(char)*rec_id_len);
  1636.   cgiFormString("record_query",rec_id,rec_id_len);
  1637.   query_len += rec_id_len;
  1638.   query=(char *)realloc(query,query_len);
  1639.   strcat(query,rec_id);
  1640.   #ifdef DEBUG
  1641.   fprintf(cgiOut,"<BR>QUERY=%s\n<BR>\n",query);
  1642.   #endif
  1643.   msqlQuery(sock,query);
  1644.   free(query);
  1645.   free(rec_id);
  1646.   free(rec_new);
  1647. }
  1648.  
  1649. void giveBackOriginalQuery(void)
  1650. {
  1651.   cgiFormString("total_query",qbuf,MAX_TEXTQUERY_LEN);
  1652.   doSearchQuery();
  1653.   giveSearchForm();
  1654. }
  1655.