Sei sulla pagina 1di 34

Tutorial: Using Metrowerks

CodeWarrior and ODBC


with Adaptive Server
Anywhere 9.0.1 on Mac OS
X

A whitepaper from iAnywhere Solutions, Inc.,


a subsidiary of Sybase, Inc.
Contents
Overview 2

Requirements 2

Setting up the ODBC environment 3

Creating a new project 6

Adding code to the project 7


Adding files to the project . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

Configuring the target 9


Setting the prefix.h file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Adding search/access paths . . . . . . . . . . . . . . . . . . . . . . . . . 10
Adding the deployment/runtime environment variables . . . . . . . . . . . 11
Adding the ODBC library to the project . . . . . . . . . . . . . . . . . . . . 12
Copying the interface into the project . . . . . . . . . . . . . . . . . . . . . 12
Building and running the project . . . . . . . . . . . . . . . . . . . . . . . 13

Appendix A: odbcex.c 14

Appendix B: odbcex.h 21

Appendix C: ContactController.m 24

Appendix D: ContactController.h 28

Appendix E: example.h 29

Appendix F: Sample odbc.ini and odbcinst.ini 31

Appendix G: environment.plist 32

Legal Notice 33
Contact Us . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

1
Copyright © 2004 iAnywhere Solutions, Inc.

Overview
This tutorial helps you create a sample Cocoa application with Metrowerks
CodeWarrior on Mac OS X that queries the contact table within the Adaptive
Server Anywhere sample database (asademo.db). The application provides the
ability move through the contact table with a bi-directional cursor and save
changes to Street and Zip data. The end result should appear as follows:

The document does not attempt to assist you with coding with ODBC or with
coding in Objective-C, C, or C++; there are many resources available to assist you
with these topics on the web. Instead, the document assists you in building a
Code Warrior project by putting together the required components within the IDE.

Requirements
♦ SQL Anywhere Studio 9.0.1 for Mac OS X, or later
♦ Mac OS X 10.2.3 or later
♦ CodeWarrior 8.0 or later

2
Copyright © 2004 iAnywhere Solutions, Inc.

♦ ODBC Driver Manager

Setting up the ODBC environment


Before you can create an ODBC data source, you must first add the Adaptive
Server Anywhere ODBC driver. If you have already done this, proceed to the next
set of steps for creating an ODBC data source.

❖ To add the Adaptive Server Anywhere ODBC driver


1. Launch the OpenLink ODBC Administrator from /Applications/Utilities.
2. Select the ODBC Drivers tab.
3. Click Add a Driver.
The ODBC Driver Add/Setup dialog appears.

4. In the Description field, type ASA 9.0 Driver.


5. Click Browse and select the Adaptive Server Anywhere ODBC driver in both
the Driver File Name and Setup File Name fields. By default, it is located in
/Applications/SQLAnywhere9/System/lib/dbodbc9.bundle.

6. Click OK.
Once you have added the Adaptive Server Anywhere ODBC driver, you can
create an ODBC data source that will be used to connect to the database.

❖ To create an ODBC data source


1. Launch the ODBC Administrator from /Applications/Utilities.

3
Copyright © 2004 iAnywhere Solutions, Inc.

If you have downloaded the OpenLink Driver Manager, it is recommended that


you use that tool. If you are not sure, the following figure illustrates the
OpenLink ODBC Administrator:

The following figure illustrates the iODBC ODBC Administrator.

2. In the ODBC Administrator, click the User DSN tab, and then click Add.
3. Choose the ASA 9.0 driver from the list of available drivers. Click OK.
4. Type ASATutorial in the Data Source Name field and add the following
connection parameters, as shown below.

4
Copyright © 2004 iAnywhere Solutions, Inc.

Keyword Value

UID dba

PWD sql
START dbeng9

DBF /Applications/SQLAnywhere9/System/asademo.db

ThreadManager ON

Driver /Applications/SQLAnywhere9/System/lib/libdbodbc9.-
bundle

In some cases, the Driver parameter may not appear in the keywords list once
it is entered. If you want to confirm that the Driver parameter is included in the
data source, you can check the list of parameters in the $
Home/Library/ODBC/odbc.ini file.
☞ For more information about connections, refer to the “Connection and
Communication Parameters” chapter of the Adaptive Server Anywhere
Database Administration Guide.

5. Click Add.
6. Press C OMMAND+Q to exit the OpenLink Driver Manager or the iODBC ODBC
Administrator.
Alternatively, you can add the information with a text editor. The ODBC
configuration files are located in Library/ODBC within your Home folder. There is
an odbcinst.ini file for driver information and an odbc.ini file for data source
information. Sample files can be found in “Appendix F: Sample odbc.ini and
odbcinst.ini” on page 31.

5
Copyright © 2004 iAnywhere Solutions, Inc.

Creating a new project


This section tells you how to create the new project in CodeWarrior.

❖ To create a new project


1. From the File menu, choose New.
The New dialog appears.

2. On the Project tab, select Mac OS X Cocoa Stationary from the list, and type
contactsample as the name of the project in the Project Name field.
3. Click OK.
4. Choose Objective-C Application project stationary, which should be the
default.
5. Click OK.
The CodeWarrior IDE appears.

6
Copyright © 2004 iAnywhere Solutions, Inc.

Adding code to the project


❖ To add code to the project
1. From the File menu, choose New.
The New dialog appears.
2. Select the File tab and click Text File. In the right pane, type prefix.h in the
Name field.

3. Click Set to browse to the project folder in the Location field.


4. Add the following code to the text editor:
#define _MSL_USING_MW_C_HEADERS 1
#include <MSL CocoaHeaders.h>
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#endif
#define MACOSX
#define UNIX
#define __OBJC__
#define PageSize 1

5. From the File menu, choose Close.


6. Save the prefix.h file in the project folder.

7. Choose File ➤ New.


The New dialog appears.
8. Select the File tab and click Text File. In the left pane, type odbcex.c in the
Name field and type the project folder in the Location field.
9. When prompted with an empty text editor, copy the code from “Appendix A:
odbcex.c” on page 14 into the text editor.

7
Copyright © 2004 iAnywhere Solutions, Inc.

10. Close the odbcex.c file and save it in the project folder.
11. Choose File ➤ New.
The New dialog appears.
12. Select the File tab and click Text File. In the left pane, type odbcex.h in the
Name field and type the project folder in the Location field.
13. When prompted with an empty text editor, copy the code from “Appendix B:
odbcex.h” on page 21 into the text editor.
14. Close the odbcex.h file and save it in the project folder.
15. Choose File ➤ New.
The New dialog appears.
16. Select the File tab and click Text File. In the left pane, type
ContactController.m in the Name field and type the project folder in the
Location field.
17. When prompted with an empty text editor, copy the code from “Appendix C:
ContactController.m” on page 24 into the text editor.
18. Close the ContactController.m file and save it in the project folder. If you get a
warning about a file mapping, ignore it.
19. Choose File ➤ New.
The New dialog appears.
20. Select the File tab and click Text File. In the left pane, type
ContactController.h in the Name field and type the project folder in the
Location field.
21. When prompted with an empty text editor, copy the code from “Appendix D:
ContactController.h” on page 28 into the text editor.
22. Close the ContactController.h file and save it in the project folder.
23. Choose File ➤ New.
The New dialog appears.
24. Select the File tab and click Text File. In the left pane, type example.h in the
Name field and type the project folder in the Location field.
25. When prompted with an empty text editor, copy the code from “Appendix E:
example.h” on page 29 into the text editor.
26. Close the example.h file and save it in the project folder.

Adding files to the project

❖ To add files to the project


1. With the CodeWarrior IDE in focus, from the Project menu choose Add Files.
A dialog appears prompting you to select files to add to the project.

8
Copyright © 2004 iAnywhere Solutions, Inc.

2. Navigate to the project folder.


3. Press S HIFT and select the prefix.h file you created. Click Choose.

4. Use the default settings in this dialog. Click OK.


5. Repeat steps 1 through 4 to add the following files to the project:
♦ odbcex.c
♦ odbcex.h
♦ ContactController.m
♦ ContactController.h
♦ example.h

Configuring the target

Setting the prefix.h file

❖ To set the prefix.h file


1. Return to the CodeWarrior IDE.
2. From the Edit menu, choose Cocoa Debug Settings.
The Cocoa Debug Settings dialog appears.
3. If you are using version CodeWarrior version 8, do the following: in the left
pane, choose Language Settings ➤ C/C++ Language. In the Prefix File field at
the bottom of the right pane, type prefix.h. Click Save.

If you are using CodeWarrior version 9, add the line #include "prefix.h" to
the beginning of the prefix file, as follows:

9
Copyright © 2004 iAnywhere Solutions, Inc.

4. After removing focus from this pane, you may be prompted to build/make the
project. Click OK to complete the project.

Adding search/access paths


In the Cocoa Debug Settings dialog, you must also add the Adaptive Server
Anywhere header files to the search path.

❖ To add search/access paths to the project


1. In the left pane of the Cocoa Debug Settings dialog, choose Access Paths.
2. In the right pane, Select the User Paths lists and then click Add.
A dialog appears prompting you to choose a folder.
3. Navigate to the include folder located within your Adaptive Server Anywhere
installation and then click Choose. By default, this folder is located in
/Applications/SQLAnywhere/System/include. The result should look similar to
the following:

10
Copyright © 2004 iAnywhere Solutions, Inc.

Adding the deployment/runtime environment variables


You can also add the runtime environment variables to your project from the
Cocoa Debug Settings dialog.

❖ To add deployment/runtime environment variables to your project


1. In the left pane of the Cocoa Debug Settings dialog, choose Target ➤ Runtime
Settings.
♦ ODBCINI environment variable The ODBCINI environment variable can
be set to Library/ODBC/odbc.ini, found within your home folder (for example,
/Users/demo/Library/ODBC/odbc.ini).
♦ DYLD_LIBRARY_PATH environment variable The
DYLD_LIBRARY_PATH environment variable can be set to the lib folder
within your Adaptive Server Anywhere installation directory.
♦ PATH environment variable The PATH environment variable can be set to
the bin folder within your Adaptive Server Anywhere installation directory.
To add an environment variable to the runtime environment, type the
environment variable name in the Variable text box, and type the environment
variable value in the Value text box.

2. Click Add to set these environment settings.


Your settings should look similar to the following:

11
Copyright © 2004 iAnywhere Solutions, Inc.

Adding the ODBC library to the project

❖ To add the ODBC library to the project


1. From the Project menu, choose Add Files.
You are prompted to choose files to add.
2. Select a library and then click choose. The following guidelines can help you
select the correct library:
♦ If you are planning to link directly to the Adaptive Server Anywhere ODBC
driver, use Finder to navigate to the lib folder in your Adaptive Server
Anywhere installation directory. Select libdbodbc9.dylib.
♦ If you are building a threaded application, select libdbodbc9.dylib.
♦ If you are planning to use the iODBC or OpenLink drivers, navigate to the
/usr/lib folder. Depending on whether or not you installed OpenLink, you may
find two files in /usr/lib to link to. Select one of the following files:
libiodbc.dylib or libiodbc2.1.6.dylib (OpenLink library). The OpenLink driver
has been known to be more stable.

Copying the interface into the project


Creating an interface is well-documented on http://developer.apple.-
com/documentation/Cocoa/Conceptual/ObjCTutorial/chapter03/chapter_3_-
section_1.html. This site provides tips for building Cocoa applications. This
document is not intended to duplicate this information. Instead, to help you along,
you can download the interface files and overwrite the existing interface for this
project.

❖ To copy the interface into the project


1. Position CodeWarrior’s IDE so that it is accessible to drop a resource from
another source.

12
Copyright © 2004 iAnywhere Solutions, Inc.

2. Using Finder, locate


/Applications/SQLAnywhere9/samples/asa/ObjectiveC/ContactSample/Tutorial/src/English.-
lproj.
3. Drag the English.lproj file onto the CodeWarrior IDE to make a reference to it in
the project.

Building and running the project

❖ To build and run the project


1. From the Project menu, choose Make to build the application. The build
process should succeed.
2. From the Project menu, choose Run to run the application.
3. Click Connect. You should see the following on your screen.

13
Copyright © 2004 iAnywhere Solutions, Inc.

Appendix A: odbcex.c
/*
* odbcex.c
* t
*
* Created by iAnywhere Solutions, demo user on Fri Jun 11 2004.
* Copyright ©) 2004 __MyCompanyName__. All rights reserved.
*
*/

// *******************************************************************
// Copyright 1994-2002 iAnywhere Solutions, Inc. All rights reserved.
// *******************************************************************
/* ODBCEX.C General ODBC code for Odbcex example (all platforms)

*/

#include "odbcex.h"
#include <string.h>
#if defined( MACOSX )
#include <stdlib.h>
#else
#include <malloc.h>
#endif
#include <ctype.h>
#include <stdlib.h>
#include "example.h"

#if defined( UNIX )


#include "unixodbc.h"
#elif defined( UNDER_CE )
#if !defined( UNICODE )
#define UNICODE
#endif
#include "ntodbc.h"
#if defined( SQL_NOUNICODEMAP )
// These two macros are required since Windows CE is UNICODE, but we
// define SQL_NOUNICODEMAP to get the ASCII ODBC functions
#define EX_SQL_C_TCHAR SQL_C_CHAR
#define EX_SQLTCHAR SQLCHAR

14
Copyright © 2004 iAnywhere Solutions, Inc.

// This code is not thread-safe since it uses a global buffer.

static wchar_t UnicodeBuffer[ 256 ];


static char MultiByteBuffer[ 256 ];

#define WindowToDB_cnv( s ) (WideCharToMultiByte( \


CP_ACP, \
0, \
s, \
-1, \
(LPSTR) MultiByteBuffer,\
sizeof( MultiByteBuffer ),\
NULL, \
NULL ), \
MultiByteBuffer)
#define DBToWindow_cnv( s ) (MultiByteToWideChar( \
CP_ACP, \
0, \
(LPCSTR) s, \
-1, \
UnicodeBuffer, \
_countof( UnicodeBuffer ) ),\
UnicodeBuffer)
#define _DBTEXT( s ) (EX_SQLTCHAR ODBCFAR *) s
#endif
#elif defined( __NT__ ) || defined( __386__ ) || defined( _M_I386 )
#include "ntodbc.h"
#else
#error "Not sure which platform is targeted."
#endif

#if !defined( EX_SQL_C_TCHAR )


// SQL_C_TCHAR is multi-byte for UNICODE, and single byte otherwise
#define EX_SQL_C_TCHAR SQL_C_TCHAR
#endif

#if !defined( EX_SQLTCHAR )


#define EX_SQLTCHAR SQLTCHAR
#endif

#if !defined( WindowToDB_cnv )


#define WindowToDB_cnv( s ) (s)
#endif

#if !defined( DBToWindow_cnv )


#define DBToWindow_cnv( s ) (s)
#endif

#if !defined( _DBTEXT )


#define _DBTEXT( s ) (EX_SQLTCHAR ODBCFAR *) TEXT(s)
#endif

#define SQL_MAX_NAME_LEN 200

15
Copyright © 2004 iAnywhere Solutions, Inc.

TCHAR TableName[ NAME_LEN ];


a_column * Columns = NULL;
SWORD NumColumns;
HENV Environment;
HDBC Connection;
HSTMT Statement;

int test_cursor_open( void )


{
if( Statement == NULL ) {
return( FALSE );
}
return( TRUE );
}
int retcode( RETCODE rcode, HSTMT stmt )
{
EX_SQLTCHAR sqlstate[ 6 ];
EX_SQLTCHAR error_msg[ 512 ];

if( rcode == SQL_SUCCESS || rcode == SQL_SUCCESS_WITH_INFO ) {


return( TRUE );
} else if( rcode == SQL_NO_DATA_FOUND ) {
return( FALSE );
} else {
SQLError( Environment, Connection, stmt, sqlstate, NULL,
error_msg, _countof( error_msg ), NULL );
return( FALSE );
}
}
void make_columns( HSTMT statement )
{
EX_SQLTCHAR colname[ NAME_LEN + 1 ];
SWORD namelen;
UWORD col;
SQLLEN size;

retcode( SQLNumResultCols( statement, &NumColumns ), statement );


Columns = (a_column *) malloc( NumColumns * sizeof( a_column ) );
memset( Columns, 0, NumColumns * sizeof( a_column ) );
for( col = 0; col < NumColumns; ++col ) {
retcode( SQLColAttributes( statement, (UWORD) (col + 1),
SQL_COLUMN_DISPLAY_SIZE, NULL, 0, NULL, &size ), statement );
if( size > MAX_FETCH_SIZE ) {
size = MAX_FETCH_SIZE;
}
Columns[ col ].width = (int) size; // display size, not buffer size
Columns[ col ].value = (EX_SQLTCHAR *) malloc( (int)(size + 1)
* sizeof( EX_SQLTCHAR ) );
retcode( SQLBindCol( statement, (UWORD) (col + 1), EX_SQL_C_TCHAR,
Columns[ col ].value, (size + 1) * sizeof( EX_SQLTCHAR ),
&Columns[ col ].size ), statement );
retcode( SQLColAttributes( statement, (UWORD) (col + 1),
SQL_COLUMN_NAME, colname, NAME_LEN * sizeof( EX_SQLTCHAR ),
&namelen, NULL ), statement );

16
Copyright © 2004 iAnywhere Solutions, Inc.

Columns[ col ].colname = (EX_SQLTCHAR *) malloc( namelen


+ sizeof( EX_SQLTCHAR ) );
#if defined( UNICODE ) && !defined( SQL_NOUNICODEMAP )
wcscpy( Columns[ col ].colname, colname );
#else
strcpy( (char *) Columns[ col ].colname, (char *) colname );
#endif
if( Columns[ col ].width < (unsigned) namelen ) {
Columns[ col ].width = namelen;
}
if( Columns[ col ].width < NULL_TEXT_LEN ) {
Columns[ col ].width = NULL_TEXT_LEN;
}
}
}

void free_columns()
{
int col;

if( Columns != NULL ) {


for( col = 0; col < NumColumns; ++col ) {
free( Columns[ col ].value );
free( Columns[ col ].colname );
}
free( Columns );
Columns = NULL;
}
NumColumns = 0;
}
int close_cursor()
{
free_columns();
SQLFreeStmt( Statement, SQL_DROP );
Statement = NULL;
return( TRUE );
}
int open_cursor()
{
TCHAR buff[ 100 ];

if( !retcode( SQLAllocStmt( Connection, &Statement ), NULL ) ) {


return( FALSE );
}
if( !retcode( SQLSetScrollOptions( Statement, SQL_CONCUR_VALUES, SQL_SCROLL_
DYNAMIC, 1 ), Statement ) ) {
close_cursor();
return( FALSE );
}
_tcscpy( buff, TEXT( "select * from " ) );
_tcscat( buff, TableName );

if( !retcode( SQLPrepare( Statement,


(EX_SQLTCHAR ODBCFAR *) WindowToDB_cnv( buff ),
SQL_NTS ),

17
Copyright © 2004 iAnywhere Solutions, Inc.

Statement ) ) {
close_cursor();
return( FALSE );
}
SQLSetStmtOption( Statement, SQL_TXN_ISOLATION, 0 );
if( !retcode( SQLExecute( Statement ), Statement ) ) {
close_cursor();
return( FALSE );
}
make_columns( Statement );
return( TRUE );
}
int column_count()
{
return (NumColumns);
}

int column_size( int pos )


{
return (Columns[ pos ].size);
}

int get_columnstring(TCHAR ** col, int pos)


{
TCHAR * c2;
c2 = (TCHAR *) DBToWindow_cnv( Columns[ pos ].value );
//_tcscpy(col, c2);
*col = c2;

return (TRUE);
}
int exec_sql( TCHAR * cmd )
{
HSTMT stmt;
TCHAR buff[500];
if( !retcode( SQLAllocStmt( Connection, &stmt ), NULL ) )
{
return( FALSE );
}

_tcscpy( buff, cmd );

if( !retcode(SQLExecDirect( stmt ,(EX_SQLTCHAR ODBCFAR *) WindowToDB_cnv(


buff ) , SQL_NTS ), NULL))
{
return( FALSE );
}
SQLFreeStmt( stmt, SQL_DROP );
stmt = NULL;
return (TRUE );

18
Copyright © 2004 iAnywhere Solutions, Inc.

int move( long relpos )


{
//long relpos = 1;
SQLULEN numfetch;
int okay;

if( !test_cursor_open() ) {
return( FALSE );
}
if( relpos == 0 ) {
return( TRUE );
}
okay = retcode( SQLExtendedFetch( Statement,
SQL_FETCH_RELATIVE,
relpos,
&numfetch,
NULL ),
Statement );
if( okay ) {
if( numfetch == 0 ) {
return(FALSE);
}
}
return( okay );
}
int top()
{
SQLULEN numfetch;
int okay;
RETCODE rcode;

if( !test_cursor_open() ) {
return( FALSE );
}
okay = retcode( SQLExtendedFetch( Statement, SQL_FETCH_FIRST, 0,
&numfetch, NULL ), Statement );
if( okay ) {
rcode = SQLExtendedFetch( Statement,
SQL_FETCH_RELATIVE,
-1,
&numfetch,
NULL );
if( rcode != SQL_NO_DATA_FOUND ) {
okay = retcode( rcode, Statement );
}
}
return( okay );
}
int bottom()
{
SQLULEN numfetch;
int okay;

if( !test_cursor_open() ) {
return( FALSE );
}
okay = retcode( SQLExtendedFetch( Statement, SQL_FETCH_LAST, 0,
&numfetch, NULL ), Statement );
return( okay );
}

19
Copyright © 2004 iAnywhere Solutions, Inc.

int WSQLEX_Init( void )


{
if( SQLAllocEnv( &Environment ) != SQL_SUCCESS ) return( FALSE );
if( SQLAllocConnect( Environment, &Connection ) != SQL_SUCCESS ) {
SQLFreeEnv( Environment );
return( FALSE );
}
if( !retcode( SQLConnect( Connection,
_DBTEXT( "ASA" ), SQL_NTS,
_DBTEXT( "DBA" ), SQL_NTS,
_DBTEXT( "SQL" ), SQL_NTS ),
NULL ) ) {
SQLFreeConnect( Connection );
return( FALSE );
}

_tcscpy(TableName, TEXT("contact"));
open_cursor();

return( TRUE );
}
int WSQLEX_Finish()
{
close_cursor();
SQLTransact( Environment, Connection, SQL_ROLLBACK );
SQLDisconnect( Connection );
SQLFreeConnect( Connection );
SQLFreeEnv( Environment );
return( TRUE );
}

20
Copyright © 2004 iAnywhere Solutions, Inc.

Appendix B: odbcex.h
/*
* odbcex.h
* t
*
* Created by iAnywhere Solutions, demo user on Fri Jun 11 2004.
* Copyright (c) 2004 __MyCompanyName__. All rights reserved.
*
*/

// *******************************************************************
// Copyright 1994-2002 iAnywhere Solutions, Inc. All rights reserved.
// *******************************************************************
/* ODBCEX.C General ODBC code for Odbcex example (all platforms)
*/
#ifndef _ODBCEXAMPLE_H_INCLUDED
#define _ODBCEXAMPLE_H_INCLUDED
#include <string.h>
#if defined( MACOSX )
#include <stdlib.h>
#else
#include <malloc.h>
#endif
#include <ctype.h>
#include <stdlib.h>
#include "example.h"
//#import "OrderController.h"
#if defined( UNIX )
#include "unixodbc.h"
#elif defined( UNDER_CE )
#if !defined( UNICODE )
#define UNICODE
#endif
#include "ntodbc.h"
#if defined( SQL_NOUNICODEMAP )
// These two macros are required since Windows CE is UNICODE, but we
// define SQL_NOUNICODEMAP to get the ASCII ODBC functions
#define EX_SQL_C_TCHAR SQL_C_CHAR
#define EX_SQLTCHAR SQLCHAR

// This code is not thread-safe since it uses a global buffer.

static wchar_t UnicodeBuffer[ 256 ];


static char MultiByteBuffer[ 256 ];

#define WindowToDB_cnv( s ) (WideCharToMultiByte( \


CP_ACP, \
0, \
s, \
-1, \
(LPSTR) MultiByteBuffer,\
sizeof( MultiByteBuffer ),\
NULL, \
NULL ), \
MultiByteBuffer)

21
Copyright © 2004 iAnywhere Solutions, Inc.

#define DBToWindow_cnv( s ) (MultiByteToWideChar( \


CP_ACP, \
0, \
(LPCSTR) s, \
-1, \
UnicodeBuffer, \
_countof( UnicodeBuffer ) ),\
UnicodeBuffer)
#define _DBTEXT( s ) (EX_SQLTCHAR ODBCFAR *) s
#endif
#elif defined( __NT__ ) || defined( __386__ ) || defined( _M_I386 )
#include "ntodbc.h"
#else
#error "Not sure which platform is targeted."
#endif

#if !defined( EX_SQL_C_TCHAR )


// SQL_C_TCHAR is multi-byte for UNICODE, and single byte otherwise
#define EX_SQL_C_TCHAR SQL_C_TCHAR
#endif
#if !defined( EX_SQLTCHAR )
#define EX_SQLTCHAR SQLTCHAR
#endif

#if !defined( WindowToDB_cnv )


#define WindowToDB_cnv( s ) (s)
#endif

#if !defined( DBToWindow_cnv )


#define DBToWindow_cnv( s ) (s)
#endif

#if !defined( _DBTEXT )


#define _DBTEXT( s ) (EX_SQLTCHAR ODBCFAR *) TEXT(s)
#endif
#define SQL_MAX_NAME_LEN 200

typedef struct a_column {


EX_SQLTCHAR * value;
SQLLEN size; /* size of value fetched */
EX_SQLTCHAR * colname;
unsigned int width;
} a_column;

//TCHAR TableName[ NAME_LEN ];


//extern a_column * Columns = NULL;
//SWORD NumColumns;
//HENV Environment;
//HDBC Connection;
//HSTMT Statement;
int test_cursor_open( void );
int retcode( RETCODE rcode, HSTMT stmt );
void make_columns( HSTMT statement );
void free_columns();
int close_cursor();
int open_cursor();
int column_count();
int column_size( int pos );
int get_columnstring(TCHAR ** col, int pos );
int exec_sql( TCHAR * cmd );
int move( long );

22
Copyright © 2004 iAnywhere Solutions, Inc.

int top();
int bottom();
int WSQLEX_Init( void );
void WSQLEX_Process_Command( int selection );
int WSQLEX_Finish();
#endif //ODBCEXAMPLE_INCLUDED

23
Copyright © 2004 iAnywhere Solutions, Inc.

Appendix C: ContactController.m
/*
* ContactController.m
* t
*
* Created by iAnywhere Solutions, demo user on Fri Jun 11 2004.
* Copyright (c) 2004 __MyCompanyName__. All rights reserved.
*
*/
#import "ContactController.h"

@implementation ContactController
- (IBAction)connect:(id)sender
{
TCHAR * connectTxt = "Connected";
TCHAR * unconnectTxt = "Disconnected";

if ((WSQLEX_Init()==1 && isConnected == FALSE))


{
isConnected = TRUE;

if ( move((long ) 1) == TRUE )
{

[self Displaytext:connectTxt];
[self Displaycolumndata];

}
else
{
isConnected = FALSE;
[self Display_systemerror:unconnectTxt];
}

}
- (IBAction)disconnect:(id)sender
{
TCHAR * unconnectTxt = "Disconnected";
TCHAR * emptytxt = " ";
int i;
if (isConnected == TRUE )
{
if ((WSQLEX_Finish()==1 ))
{
isConnected = FALSE;
[self Displaytext:unconnectTxt];
for( i = 0; i < 10; ++i )
{
[self Displaystringtext:i buff:emptytxt];
}
}
}
}

24
Copyright © 2004 iAnywhere Solutions, Inc.

- (IBAction)next:(id)sender
{
if (isConnected == TRUE )
{

if ( move(1) == TRUE )
{

[self Displaycolumndata];

}
}
}
- (IBAction)previous:(id)sender
{
if (isConnected == TRUE )
{

if ( move( -1 ) == TRUE )
{

[self Displaycolumndata];

}
}
}
- (IBAction)save:(id)sender
{
int cmdLength;
TCHAR * cmdBuffer=0;
TCHAR * updtxt = "UPDATE contact SET zip = ’";

cmdLength = 67 + [[zipOutlet stringValue] cStringLength];


cmdLength += [[zipOutlet stringValue] cStringLength];
cmdLength += [[idOutlet stringValue] cStringLength];
cmdBuffer = malloc ( cmdLength);
_tcscpy( cmdBuffer , updtxt );
_tcscat( cmdBuffer , [[zipOutlet stringValue] cString] );
_tcscat( cmdBuffer , "’, street= ’" );
_tcscat( cmdBuffer , [[streetOutlet stringValue] cString] );
_tcscat( cmdBuffer , "’ where id =" );
_tcscat( cmdBuffer , [[idOutlet stringValue] cString] );

exec_sql( cmdBuffer );
}
-(int)Displaycolumndata
{
int i;
TCHAR *data;
TCHAR * emptytxt = " ";

for( i = 0; i < column_count(); ++i )


{

25
Copyright © 2004 iAnywhere Solutions, Inc.

if( column_size(i) != SQL_NULL_DATA )


{
get_columnstring( &data, i);
[self Displaystringtext:i buff:data];
}
else
{
[self Displaystringtext:i buff:emptytxt];
}
}
return(TRUE);

- (void)Displaystringtext:(int)pos buff:(TCHAR *)str


{

//NSString *txt = [gettext stringValue];


NSString * txt = [[NSString alloc] initWithCString:str];
switch (pos)
{
case 0:
[idOutlet setStringValue: txt];
break;
case 1:
[lastnameOutlet setStringValue: txt];
/* NSLog("%s",str); */
break;
case 2:
[firstnameOutlet setStringValue: txt];
break;
case 3:
[titleOutlet setStringValue: txt];
break;
case 4:
[streetOutlet setStringValue: txt];
break;
case 5:
[cityOutlet setStringValue: txt];
break;
case 6:
[stateOutlet setStringValue: txt];
break;
case 7:
[zipOutlet setStringValue: txt];
break;
case 8:
[phoneOutlet setStringValue: txt];
break;
case 9:
[faxOutlet setStringValue: txt];
break;
default:
break;
}

26
Copyright © 2004 iAnywhere Solutions, Inc.

- (int)Display_systemerror:(TCHAR *)msg
{
return ([self Displaytext:msg]);

}
- (int)Displaytext:(TCHAR *)msg
{
NSString * txt = [[NSString alloc] initWithCString:msg];

[infoOutlet setStringValue: txt];


return (1);
}

@end

27
Copyright © 2004 iAnywhere Solutions, Inc.

Appendix D: ContactController.h
/*
* ContactController.h
* t
*
* Created by iAnywhere Solutions, demo user on Fri Jun 11 2004.
* Copyright (c) 2004 __MyCompanyName__. All rights reserved.
*
*/
/* ContactController */

#import <Cocoa/Cocoa.h>
#include "example.h"
#include "odbcex.h"
@interface ContactController : NSObject
{
IBOutlet id idOutlet;
IBOutlet id lastnameOutlet;
IBOutlet id firstnameOutlet;
IBOutlet id titleOutlet;
IBOutlet id streetOutlet;
IBOutlet id cityOutlet;
IBOutlet id stateOutlet;
IBOutlet id zipOutlet;
IBOutlet id phoneOutlet;
IBOutlet id faxOutlet;
IBOutlet id infoOutlet;
BOOL isConnected;

}
- (IBAction)connect:(id)sender;
- (IBAction)disconnect:(id)sender;
- (IBAction)next:(id)sender;
- (IBAction)previous:(id)sender;
- (IBAction)save:(id)sender;
- (int)Displaycolumndata;
- (void)Displaystringtext:(int)pos buff:(TCHAR *)str;
- (int)Display_systemerror:(TCHAR *)msg;
- (int)Displaytext:(TCHAR *)msg;

@end

28
Copyright © 2004 iAnywhere Solutions, Inc.

Appendix E: example.h
// *******************************************************************
// Copyright 1994-2004 iAnywhere Solutions, Inc. All rights reserved.
// *******************************************************************
/* EXAMPLE.H Common header file for all examples
*/
#ifndef _EXAMPLE_H_INCLUDED
#define _EXAMPLE_H_INCLUDED
#if defined( __WINDOWS_386__ ) \
|| defined( __NT__ ) \
|| (defined( __386__ ) && !defined( LINUX ) && !defined( SUN )) \
|| defined( _M_I386 ) \
|| defined( UNDER_CE )
// Get definition for TCHAR and related functions.
#include <windows.h>
#include <tchar.h>
#else
// Define TCHAR and related functions.
typedef char TCHAR;
#define _tcslen(s) strlen(s)
#define _tcscpy(d,s) strcpy(d,s)
#define _tcscat(d,s) strcat(d,s)
#define _tcsncpy(d,s,n) strncpy(d,s,n)
#define _stprintf sprintf
#define _vstprintf vsprintf
#define LPTSTR LPSTR
#ifndef TEXT
#define TEXT(s) s
#endif
#endif

#define _countof( array ) (sizeof( array )/sizeof( array[0] ))


//int PageSize = 1;
//int Displaytext( int, TCHAR *, ... );
//int Displaystringtext( int, int, TCHAR * );
//void Display_systemerror( TCHAR * );
//void Display_refresh( void );
//void GetValue( TCHAR *, TCHAR *, int );
//void GetTableName( TCHAR *, int );
int WSQLEX_Init( void );
void WSQLEX_Process_Command( int );
int WSQLEX_Finish( void );
#define IDM_HELP 101
#define IDM_PRINT 102
#define IDM_UP 103
#define IDM_DOWN 104
#define IDM_BOTTOM 105
#define IDM_TOP 106
#define IDM_QUIT 107
#define IDM_NAME 108
#define IDM_INSERT 109
#define IDE_STRING_EDIT 101
//#if !defined( TRUE )
// #define TRUE 1
//#endif

29
Copyright © 2004 iAnywhere Solutions, Inc.

//#if !defined( FALSE )


// #define FALSE 0
//#endif
#define MAX_TABLE_NAME 50
#define NAME_LEN 50
#define MAX_FETCH_SIZE 50
#define DEFAULT_SCREEN_WIDTH 79
#define MAX_SCREEN_WIDTH 1024
#define NULL_TEXT TEXT( "(NULL)" )
#define NULL_TEXT_LEN _countof( NULL_TEXT )
#if defined(_MSC_VER)
#if _MSC_VER >= 800
#define _exportkwd
#else
#define _exportkwd _export
#endif
#elif defined(__WATCOMC__)
#define _exportkwd __export
#else
#define _exportkwd _export
#endif
#define MY_NEWLINE_STR TEXT( "\n" )
#define MY_NEWLINE_CHAR ’\n’
#endif //_EXAMPLE_H_INCLUDED

30
Copyright © 2004 iAnywhere Solutions, Inc.

Appendix F: Sample odbc.ini and


odbcinst.ini
ODBCINST.INI
[ODBC Drivers]
ASA 9.0 Driver = Installed

[ASA 9.0 Driver]


Driver = /Applications/SQLAnywhere9/System/lib/dbodbc9_r.bundle
Setup = /Applications/SQLAnywhere9/System/lib/dbodbc9_r.bundle

[ODBC Connection Pooling]


PerfMon = 0
Retry Wait =

ODBC.INI
[ODBC Data Sources]
ASA = ASA 9.0 Driver

[ASA]
Driver = /Applications/SQLAnywhere9/System/lib/dbodbc9_r.bundle
uid = dba
pwd = sql
start = dbeng9
dbf = /Applications/SQLAnywhere9/System/asademo.db
ThreadManager = on

[ODBC]
Trace = 0
TraceAutoStop = 0
TraceFile = /Users/demo/sql.log
TraceDLL =

31
Copyright © 2004 iAnywhere Solutions, Inc.

Appendix G: environment.plist
This file is located in $HOME/.MacOSX/environment.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ODBCINI</key>
<string>/Users/demo/Library/ODBC/odbc.ini</string>

<key>DYLD_LIBRARY_PATH</key>
<string>/Applications/SQLAnywhere9/System/lib</string>

<key>DYLD_BIND_AT_LAUNCH</key>
<string>1</string>
<key>CLASSPATH</key>
<string>/Applications/SQLAnywhere9/System/java/jodbc.jar:/Applications/SQLAnywhe
re9/shared/jConnect-5_5/classes/jconn2.jar</string>

<key>ASANY9</key>
<string>/Applications/SQLAnywhere9/System</string>

<key>ASANYSH9</key>
<string>/Users/demo/shared</string>
<key>PATH</key>
<string>/bin:/sbin:/usr/bin:/usr/sbin:/Applications/SQLAnywhere9/System/bin</str
ing>

</dict>
</plist>

32
Copyright © 2004 iAnywhere Solutions, Inc.

Legal Notice
Copyright © 2004 iAnywhere Solutions, Inc. All rights reserved. Sybase, the
Sybase logo, iAnywhere Solutions, the iAnywhere Solutions logo, Adaptive
Server, MobiLink, and SQL Anywhere are trademarks of Sybase, Inc. or its
subsidiaries. All other trademarks are property of their respective owners
The information, advice, recommendations, software, documentation, data,
services, logos, trademarks, artwork, text, pictures, and other materials
(collectively, “Materials”) contained in this document are owned by Sybase, Inc.
and/or its suppliers and are protected by copyright and trademark laws and
international treaties. Any such Materials may also be the subject of other
intellectual property rights of Sybase and/or its suppliers all of which rights are
reserved by Sybase and its suppliers.
Nothing in the Materials shall be construed as conferring any license in any
Sybase intellectual property or modifying any existing license agreement.
The Materials are provided “AS IS”, without warranties of any kind. SYBASE
EXPRESSLY DISCLAIMS ALL REPRESENTATIONS AND WARRANTIES
RELATING TO THE MATERIALS, INCLUDING WITHOUT LIMITATION, ANY
IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NON-INFRINGEMENT. Sybase makes no warranty,
representation, or guaranty as to the content, sequence, accuracy, timeliness, or
completeness of the Materials or that the Materials may be relied upon for any
reason.
Sybase makes no warranty, representation or guaranty that the Materials will be
uninterrupted or error free or that any defects can be corrected. For purposes of
this section, ‘Sybase’ shall include Sybase, Inc., and its divisions, subsidiaries,
successors, parent companies, and their employees, partners, principals, agents
and representatives, and any third-party providers or sources of Materials.

Contact Us
iAnywhere Solutions Worldwide Headquarters One Sybase Drive, Dublin,
CA, 94568 USA
Phone 1-800-801-2069 (in US and Canada)
Fax 1-519-747-4971
World Wide Web http://www.ianywhere.com
E-mail contact.us@ianywhere.com

33

Potrebbero piacerti anche