home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 January: Mac OS SDK / Dev.CD Jan 96 SDK / Dev.CD Jan 96 SDK1.toast / Development Kits (Disc 1) / MacODBC / ODBC Tools / SampleSetup / Sources / SampleSetup.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-26  |  11.0 KB  |  374 lines  |  [TEXT/MPS ]

  1. /*
  2.  *    ODBCdbmsSetup.c -- ODBC Sample DBMS Setup Shared Library (or DLL).
  3.  *
  4.  *    (c) Apple Computer, Inc 1993
  5.  *
  6.  *    changes:
  7.  *
  8.  *    1.0a1    -    removed all calls to OpenGlobalWorld, as this is compiled model far
  9.  *                and doesn't have any A5-relative references to globals. Also
  10.  *                removed code to set up the QuickDraw environment, e.g. calls to 
  11.  *                InitGraf, etc., as these should not be done more than once from a process.
  12.  *                A5 world is assumed to have valid QD globals when this shared library is called.
  13.  */
  14.  
  15. #include <Dialogs.h>
  16. #include <Fonts.h>
  17. #if ! PPCODBC
  18. #include <LibraryManagerUtilities.h>
  19. #endif // ! PPCODBC
  20. #include <Menus.h>
  21. #include <OSUtils.h>
  22. #include <QuickDraw.h>
  23. #include <StdIO.h>
  24. #include <String.h>
  25. #include <TextEdit.h>
  26. #include <Windows.h>
  27.  
  28. #include "DBMSsetup.h"
  29. #include "ODBCINST.H"
  30. #include "ODBCSharedLibraries.h"
  31.  
  32. #include "SampleSetup.h"
  33.  
  34. /*
  35.  *    data source keywords
  36.  */
  37.  
  38. LPCSTR kDefaultDataSourceName    = "Default";            // default data source name
  39. LPCSTR kDataSourceNameKeyword    = "DSN";                // data source name keyword
  40. LPCSTR kDescriptionKeyword        = "Description";        // data source description keyword
  41. LPCSTR kOtherKeyword            = "Other";                // other keyword
  42. LPCSTR kTranslateDLLKeyword        = "TranslateDLL";        // translate DLL
  43. LPCSTR kTranslateKeyword        = "Translate";            // translate keyword
  44. LPCSTR kTranslateOptionKeyword    = "TranslateOption";    // translate option keyword
  45. LPCSTR kNoTranslation            = "No Translation";        // no translation
  46. LPCSTR kEmptyString                = "";                    // empty string
  47. LPCSTR kODBCINI                    = "ODBC.INI";
  48.  
  49. /*
  50.  *    prototypes
  51.  */
  52.  
  53. static INSTPREAPI BOOL INSTAPI    DoConfigDSN                        (WindowPtr parentWindow, UINT fRequest, LPCSTR lpszDriver, LPCSTR lpszAttributes);
  54. static INSTPREAPI BOOL INSTAPI    RemoveDataSource                (WindowPtr parentWindow, LPCSTR lpszDriver, DataSourceInfo *info);
  55. static INSTPREAPI BOOL INSTAPI    AddDataSource                    (WindowPtr parentWindow, LPCSTR lpszDriver, DataSourceInfo *info);
  56. static INSTPREAPI BOOL INSTAPI    ConfigureDataSource                (WindowPtr parentWindow, LPCSTR lpszDriver, DataSourceInfo *info);
  57. static INSTPREAPI BOOL INSTAPI    ParseAttributes                    (LPCSTR lpszAttributes, DataSourceInfo *info);
  58. static INSTPREAPI BOOL INSTAPI    GetKeywordValueFromAttributes    (LPCSTR lpszKeyword, LPCSTR lpszAttributes, LPSTR lpszString);
  59.  
  60. /*
  61.  *    public functions
  62.  */
  63.  
  64. #if PPCODBC
  65.  
  66. #include <Memory.h>
  67. #include <Errors.h>
  68.  
  69. Handle hinst;
  70.  
  71. // _____________________________________________________________________________
  72.     OSErr
  73.     SampleSetupInit( InitBlockPtr ib )
  74. {
  75.     /*
  76.      *    shared library init function.  All shared libraries should have one.  Its name is
  77.      *    declared in the .exp file.
  78.      */
  79.  
  80.     if ( ib->fragLocator.where != kOnDiskFlat ) { return -32323; }
  81.     
  82.     hinst = NewHandle( sizeof( ODBCLibConnection ) );
  83.     if ( ! hinst ) { return memFullErr; }
  84.     HLock( hinst );
  85.     
  86.     (*(ODBCLibConnection**)hinst)->spec = *ib->fragLocator.u.onDisk.fileSpec;
  87.     (*(ODBCLibConnection**)hinst)->connId = ib->connectionID;
  88.     
  89.     HUnlock( hinst );
  90.     
  91.     return noErr;
  92. }
  93.  
  94.  
  95. // _____________________________________________________________________________
  96.     void 
  97.     SampleSetupMain( Handle inst2init )
  98. {
  99.     HLock( hinst );
  100.     HLock( inst2init );
  101.     **(ODBCLibConnection**)inst2init = **(ODBCLibConnection**)hinst;
  102.     HUnlock( hinst );
  103.     HUnlock( inst2init );
  104. }
  105.  
  106.  
  107. #else  // PPCODBC
  108.  
  109. // _____________________________________________________________________________
  110.     void
  111.     SampleSetupInit()
  112. {
  113.     /*
  114.      *    shared library init function.  All shared libraries should have one.  Its name is
  115.      *    declared in the .exp file.
  116.      */
  117.  
  118.     // note: hinst is not needed for the 68k ODBCSharedLibraries functions
  119. }
  120.  
  121. #endif // PPCODBC
  122.  
  123. // _____________________________________________________________________________
  124.     void
  125.     SampleSetupObit()
  126. {
  127.     /*
  128.      *    Shared library cleanup function.  All shared libraries should have one.  Its name is
  129.      *    declared in the .exp file.
  130.      */
  131.      
  132. #if PPCODBC
  133.     DisposHandle( hinst );
  134. #endif // PPCODBC
  135. }
  136.  
  137.  
  138.  
  139. INSTPREAPI BOOL INSTAPI
  140. ConfigDSN(HWND    pGrafPort,                /* window to center over                    */
  141.           UINT        fRequest,            /* add, modify or delete                    */
  142.           LPCSTR    lpszDriver,            /* name to present to user for this driver    */
  143.           LPCSTR    lpszAttributes)        /* buffer holding section data                */
  144. {
  145.     /*
  146.      *    this is the shared lilbrary entry point for configuring a data source.
  147.      *    ConfigDSN is responsible for adding, configuring and deleting a data source, and will
  148.      *    be called by the ODBC Configuration Manager.  note that the even if we're adding
  149.      *    a new data source, a data source name keyword-value pair must be present in the attributes 
  150.      *    buffer (i.e. "DSN=A Data Source Name").  in fact, when adding or deleting it can
  151.      *    be the only keyword-value pair in the attributes buffer.
  152.      */
  153.     
  154.     BOOL                success;
  155.     ODBCLibResContext    context;
  156.     
  157.     if ( ODBCLibUseLocalRes( &context ) )
  158.     {
  159.         SysBeep(1);    // can't put up our alert if ODBCLibUseLocalRes failed
  160.         return FALSE;
  161.     }
  162.     
  163.     /*
  164.      *    here's where the work gets done
  165.      */
  166.     
  167.     success = DoConfigDSN((WindowPtr) pGrafPort, fRequest, lpszDriver, lpszAttributes);
  168.     
  169.     /*
  170.      *    restore resource path, A5 world
  171.      */
  172.     
  173.     ODBCLibCloseLocalRes( &context );
  174.     
  175.     return success;
  176. }
  177.  
  178. /*
  179.  *    private functions
  180.  */
  181.  
  182. static INSTPREAPI BOOL INSTAPI
  183. DoConfigDSN(WindowPtr parentWindow, UINT fRequest, LPCSTR lpszDriver, LPCSTR lpszAttributes)
  184. {
  185.     /*
  186.      *    pull out the keyword values from the attribute buffer, then add, configure or
  187.      *    remove the data source. note that the data source name must be one of the
  188.      *    keyword values in the buffer (DSN=Data Source Name), or nothing can be done.
  189.      */
  190.     
  191.     BOOL            success = false;
  192.     DataSourceInfo    info;
  193.     
  194.     /*
  195.      *    The attributes buffer should always contain the data source name - if
  196.      *    not ParseAttributes returns false and we deign to continue
  197.      */
  198.     
  199.     if (!ParseAttributes(lpszAttributes, &info)) return false;
  200.     
  201.     /*
  202.      *    Add, Modify or Remove the data source
  203.      */
  204.     
  205.     switch (fRequest)
  206.     {
  207.         case ODBC_ADD_DSN:
  208.             success = AddDataSource(parentWindow, lpszDriver, &info);
  209.             break;
  210.         
  211.         case ODBC_CONFIG_DSN:
  212.             success = ConfigureDataSource(parentWindow, lpszDriver, &info);
  213.             break;
  214.         
  215.         case ODBC_REMOVE_DSN:
  216.             success = RemoveDataSource(parentWindow, lpszDriver, &info);
  217.             break;
  218.     }
  219.     
  220.     return success;
  221. }
  222.  
  223. static INSTPREAPI BOOL INSTAPI
  224. RemoveDataSource(WindowPtr parentWindow, LPCSTR lpszDriver, DataSourceInfo *info)
  225. {
  226.     /*
  227.      *    Call the config manager to remove the data source from the ODBC prefs file
  228.      */
  229.     
  230.     return SQLRemoveDSNFromIni(info->name);
  231. }
  232.  
  233. static INSTPREAPI BOOL INSTAPI
  234. AddDataSource(WindowPtr parentWindow, LPCSTR lpszDriver, DataSourceInfo *info)
  235. {
  236.     /*
  237.      *    Call the setup dialog on the data source info, then call the config manager to 
  238.      *    update the data source entry in the ODBC prefs file if the user clicked OK. Make
  239.      *    sure to remove the old data source entry as the user may have changed the name.
  240.      */
  241.     /*
  242.      *    Set the initial values for the new data source's keywords
  243.      */
  244.     
  245.     strcpy(info->description,        kEmptyString);
  246.     strcpy(info->other,                kEmptyString);
  247.     strcpy(info->translateDLL,        kEmptyString);
  248.     strcpy(info->translate,            kNoTranslation);
  249.     strcpy(info->translateOption,    kEmptyString);
  250.     
  251.     /*
  252.      * Now let the user set the keyword values
  253.      */
  254.     
  255.     if (!DoDBMSsetup(parentWindow, info))
  256.         return false;
  257.     
  258.     /*
  259.      *    Now add the data source and its keywords. You might want to add check that a 
  260.      *    datasource with this name doesn't already exist before writing…
  261.      */
  262.     if (!SQLWriteDSNToIni(info->name, lpszDriver)) return false;
  263.  
  264.  
  265.     if (!SQLWritePrivateProfileString(info->name, kDescriptionKeyword, info->description, kODBCINI)) return false;
  266.     if (!SQLWritePrivateProfileString(info->name, kOtherKeyword, info->other, kODBCINI)) return false;
  267.     if (!SQLWritePrivateProfileString(info->name, kTranslateDLLKeyword, info->translateDLL, kODBCINI)) return false;
  268.     if (!SQLWritePrivateProfileString(info->name, kTranslateKeyword, info->translate, kODBCINI)) return false;
  269.     if (!SQLWritePrivateProfileString(info->name, kTranslateOptionKeyword, info->translateOption, kODBCINI)) return false;
  270.  
  271.     return true;
  272. }
  273.  
  274. static INSTPREAPI BOOL INSTAPI
  275. ConfigureDataSource(WindowPtr parentWindow, LPCSTR lpszDriver, DataSourceInfo *info)
  276. {
  277.     /*
  278.      *    Call the setup dialog on the data source info, then call the config manager to 
  279.      *    update the data source entry in the ODBC prefs file if the user clicked OK. Make
  280.      *    sure to remove the old data source entry as the user may have changed the name.
  281.      */
  282.  
  283.     char    oldName[kMaxValueLength];
  284.     
  285.     strcpy(oldName, info->name);
  286.     
  287.     if (!DoDBMSsetup(parentWindow, info))
  288.         return false;
  289.     
  290.     if (!SQLRemoveDSNFromIni(oldName))
  291.         return false;
  292.     
  293.     if (!SQLWriteDSNToIni(info->name, lpszDriver))
  294.         return false;
  295.     
  296.     if (!SQLWritePrivateProfileString(info->name, kDescriptionKeyword, info->description, kODBCINI)) return false;
  297.     if (!SQLWritePrivateProfileString(info->name, kOtherKeyword, info->other, kODBCINI)) return false;
  298.     if (!SQLWritePrivateProfileString(info->name, kTranslateDLLKeyword, info->translateDLL, kODBCINI)) return false;
  299.     if (!SQLWritePrivateProfileString(info->name, kTranslateKeyword, info->translate, kODBCINI)) return false;
  300.     if (!SQLWritePrivateProfileString(info->name, kTranslateOptionKeyword, info->translateOption, kODBCINI)) return false;
  301.  
  302.     return true;
  303. }
  304.  
  305. static INSTPREAPI BOOL INSTAPI
  306. ParseAttributes(LPCSTR lpszAttributes, DataSourceInfo *info)
  307. {
  308.     /*
  309.      *    Pull out the keyword values from the data source attributes buffer.
  310.      *    If the data source name keyword, DSN, isn't found, or is zero-length, then
  311.      *    return false. All other keyword values may be absent or zero-length.
  312.      */
  313.     
  314.     if (!GetKeywordValueFromAttributes(kDataSourceNameKeyword, lpszAttributes, info->name))
  315.         return false;
  316.     
  317.     GetKeywordValueFromAttributes(kDescriptionKeyword,        lpszAttributes, info->description);
  318.     GetKeywordValueFromAttributes(kOtherKeyword,            lpszAttributes, info->other);
  319.     GetKeywordValueFromAttributes(kTranslateDLLKeyword,        lpszAttributes, info->translateDLL);
  320.     GetKeywordValueFromAttributes(kTranslateKeyword,        lpszAttributes, info->translate);
  321.     GetKeywordValueFromAttributes(kTranslateOptionKeyword,    lpszAttributes, info->translateOption);
  322.     
  323.     return true;
  324. }
  325.  
  326. static INSTPREAPI BOOL INSTAPI
  327. GetKeywordValueFromAttributes(LPCSTR lpszKeyword, LPCSTR lpszAttributes, LPSTR lpszString)
  328. {
  329.     /*
  330.      *    searches the attributes buffer (containing the packed array of keyword=value null-terminated
  331.      *    strings, with an additional null terminating the entire array) for the requested keyword,
  332.      *    and copies its value over to lpszString. lpszString should point to a buffer at least 
  333.      *    kMaxValueLength bytes long. returns true if found and non-zero, false otherwise.
  334.      */
  335.     
  336.     char    *s, *t, *u;
  337.     char    tmpKeyword[kMaxKeywordLength];
  338.     
  339.     /*
  340.      *    loop through each keyword=value string in the buffer
  341.      */
  342.     
  343.     for (lpszString[0] = 0, s = lpszAttributes; *s; s += strlen(s) + 1)
  344.     {
  345.         /*
  346.          *    pull out the keyword as a c-string
  347.          */
  348.         
  349.         for (u = s, t = tmpKeyword; *u; u++, t++)
  350.         {
  351.             if (*u == '=')
  352.             {
  353.                 u++;
  354.                 break;
  355.             }
  356.             *t = *u;
  357.         }
  358.         *t = 0;
  359.         
  360.         /*
  361.          *    if this is the desired keyword then copy its value to lpszString and beat it. u was
  362.          *    left pointing to the start of the value string from the previous operation
  363.          */
  364.         
  365.         if (strcmp(tmpKeyword, lpszKeyword) == 0)
  366.         {
  367.             strcpy(lpszString, u);
  368.             return true;
  369.         }
  370.     }
  371.     
  372.     return false;
  373. }
  374.