OPTIONS "NOSOURCE"
ADDRESS null
NUMERIC DIGITS 10
OPTIONS "WINFUNC NOSOURCE"
SIGNAL ON ERROR
SIGNAL ON SYNTAX
FUNCDEF("SQLAllocEnv", "16, void * stor", "odbc32.dll")
FUNCDEF("SQLFreeEnv", "16, void", "odbc32.dll")
FUNCDEF("SQLAllocConnect", "16, void, void * stor", "odbc32.dll")
FUNCDEF("SQLFreeConnect", "16, void", "odbc32.dll")
FUNCDEF("SQLDriverConnect", "16, void, void, char *, 32, char[512] stor, 32, 16 * stor, 32u", "odbc32.dll")
FUNCDEF("SQLDisconnect", "16, void", "odbc32.dll")
FUNCDEF("SQLAllocStmt", "16, void, void * stor", "odbc32.dll")
FUNCDEF("SQLFreeStmt", "16, void, 32u", "odbc32.dll")
FUNCDEF("SQLDrivers", "16, void, 32u, char[513] stor, 32, 16 * stor, char[513] stor, 32, 16 * stor", "odbc32.dll")
FUNCDEF("SQLTables", "16, void, char *, 32, char *, 32, char *, 32, char *, 32", "odbc32.dll")
FUNCDEF("SQLExecDirect", "16, void, char *, 32", "odbc32.dll")
FUNCDEF("SQLNumResultCols", "16, void, 16 * stor", "odbc32.dll")
FUNCDEF("SQLDescribeCol", "16, void, 32u, char[256] stor, 32, 16 * stor, 16 * stor, 32u * stor, 16 * stor, 16 * stor", "odbc32.dll")
FUNCDEF("SQLFetch", "16, void", "odbc32.dll")
FUNCDEF("SQLGetData", "16, void, 32u, 32, char[256] stor, 32, 32 * stor", "odbc32.dll")
FUNCDEF("SQLError", "16, void, void, void, char[6] stor, 32 * stor, char[512] stor, 32, 16 * stor", "odbc32.dll")
FUNCDEF("SQLSetConnectOptionInt", "16, void, 32u, 32u", "odbc32.dll", "SQLSetConnectOption")
FUNCDEF("SQLGetInfoChar", "16, void, 32u, char[256] stor, 32, 16 * stor", "odbc32.dll", "SQLGetInfo")
FUNCDEF("SQLGetInfoInt", "16, void, 32u, 16 * stor, 32, 16 * stor", "odbc32.dll", "SQLGetInfo")
FUNCDEF("SQLGetFunctions", "16, void, 32u, 16u * stor", "odbc32.dll")
FUNCDEF("SQLGetAllFunctions", "16, void, 32u, 16u[100] * stor", "odbc32.dll", "SQLGetFunctions")
FUNCDEF("SQLDataSources", "16, void, 32u, char[513] stor, 32, 16 * stor, char[513] stor, 32, 16 * stor", "odbc32.dll")
FUNCDEF("RegEnumStrValue", "32, void, 32u, str[260] stor, 32u * dual, void, 32u *, str[260] stor, 32u * dual", "advapi32.dll", "RegEnumValue")
FUNCDEF("RegOpenKey", "32, void, str, 32u * stor", "advapi32.dll")
FUNCDEF("RegCloseKey", "32, void", "advapi32.dll")
SIGNAL OFF ERROR
ERROR = odbcinit()
IF ERROR \== "" THEN DO
SAY ERROR
RETURN
END
ERROR = odbcgetdsnlist()
IF ERROR \== "" | odbc.!dsncount = 0 THEN DO
IF ERROR \== "" THEN SAY ERROR
ELSE SAY "No database drivers available"
END
again:
DO i = 1 TO odbc.!dsncount
SAY i "=" odbc.!dsn.i "(" || odbc.!dsndesc.i || ")"
END
SAY
SAY "Enter number of the desired driver"
PULL i
IF DATATYPE(i, 'W') \== 1 THEN SIGNAL again
IF i > odbc.!dsncount THEN SIGNAL again
SAY "Connecting to" odbc.!dsn.i || "..."
ERROR = odbcconnect("DSN=" || odbc.!dsn.i || ";")
IF ERROR \== "" THEN SAY ERROR
ELSE DO
SAY "To bypass the connection dialog, pass this connection string to ODBCConnect():"
SAY '"' || odbc.!connected || '"'
SAY
CALL odbcprintdriverinfo
ERROR = odbcquery("INSERT INTO demotable(demodata) VALUES('Something')")
IF ERROR \== "" THEN SAY ERROR
ELSE DO
ERROR = odbcgetrecord()
IF ERROR \== "" THEN SAY ERROR
ELSE
DO column = 1 TO odbc.!fieldcount
SAY odbc.!fielddata.column
END
END
END
odbcexit()
RETURN
syntax:
error:
CONDITION('M')
halt:
odbcexit()
RETURN
odbcprocesserror:
IF errlen == 0 THEN RETURN "ODBC API ERROR #" || ret ARG(1)
RETURN "ODBC ERROR #" || STATE LEFT(err, errlen)
odbcinit: PROCEDURE EXPOSE odbc.
ret = sqlallocenv(odbc.!glenv)
IF ret \== 0 THEN DO
errlen = 0
CALL sqlerror 0, 0, 0, STATE, statelen, err, 511 , errlen
RETURN odbcprocesserror("Can't get environment")
END
ret = sqlallocconnect(odbc.!glenv, odbc.!gldbc)
IF ret \== 0 THEN DO
errlen = 0
CALL sqlerror odbc.!glenv, 0, 0, STATE, statelen, err, 511, errlen
CALL sqlfreeenv odbc.!glenv
DROP odbc.!glenv
RETURN odbcprocesserror("Can't get database manager")
END
CALL sqlsetconnectoptionint odbc.!gldbc, 103 , 15
RETURN ""
odbcconnect: PROCEDURE EXPOSE odbc.
IF ARG(2, 'E') THEN window = ARG(2)
ELSE window = 0
errlen = 0
ret = sqldriverconnect(odbc.!gldbc, window, ARG(1), LENGTH(ARG(1)), STATE, 512, statelen, 1)
IF ret \== 0 & ret \== 1 THEN DO
errlen = 0
CALL sqlerror odbc.!glenv, odbc.!gldbc, 0, STATE, statelen, err, 511, errlen
RETURN odbcprocesserror("Can't connect to database")
END
odbc.!connected = LEFT(STATE, statelen)
ret = sqlallocstmt(odbc.!gldbc, odbc.!glstmt)
IF ret \== 0 THEN DO
errlen = 0
CALL sqlerror odbc.!glenv, odbc.!gldbc, 0, STATE, statelen, err, 511, errlen
CALL sqldisconnect odbc.!gldbc
DROP odbc.!connected
RETURN odbcprocesserror("Can't get statement handle")
END
RETURN ""
odbcgettables: PROCEDURE EXPOSE odbc.
ret = odbcfuncissupported("SQLTables")
IF ret \== "" THEN RETURN ret
ret = sqltables(odbc.!glstmt, 0, 0, 0, 0, 0, 0, "TABLE", 5 )
IF ret \== 0 THEN DO
errlen = 0
CALL sqlerror odbc.!glenv, odbc.!gldbc, odbc.!glstmt, STATE, statelen, err, 511, errlen
RETURN odbcprocesserror("Can't get table labels")
END
odbc.!table.0 = 0
DO UNTIL ret \== 0
ret = sqlfetch(odbc.!glstmt)
IF ret = -1 THEN LEAVE
IF ret == 0 | ret == 1 THEN DO
odbc.!table.0 = odbc.!table.0 + 1
DO table = 1 TO 3
ret = sqlgetdata(odbc.!glstmt, table, 1 , data, 255 , outlen)
END
IF outlen \== -1 & outlen \== 0 THEN odbc.table.[odbc.!table.0] = LEFT(data, outlen)
ELSE odbc.table.[odbc.!table.0] = ""
END
END
RETURN ""
odbcquery: PROCEDURE EXPOSE odbc.
exec = ARG(1)
ret = sqlexecdirect(odbc.!glstmt, exec, LENGTH(exec))
IF ret \== 0 & ret \== 1 THEN DO
exec = "Bad SQL statement"
odbcqueryerr:
errlen = 0
CALL sqlerror odbc.!glenv, odbc.!gldbc, odbc.!glstmt, STATE, statelen, err, 511, errlen
RETURN odbcprocesserror(exec)
END
ret = sqlnumresultcols(odbc.!glstmt, numcols)
IF ret \== 0 THEN DO
exec = "Can't get results"
SIGNAL odbcqueryerr
END
odbc.!fieldcount = numcols
DO col = 1 TO numcols
ret = sqldescribecol(odbc.!glstmt, col, colname, 255 , colnamelen, dtype, colsize, DIGITS, av)
IF ret \== 0 THEN DO
exec = "Can't get column descriptions"
SIGNAL odbcqueryerr
END
SELECT
WHEN dtype == 1 THEN odbc.!fieldtypestr.col = "CHAR"
WHEN dtype == 2 THEN odbc.!fieldtypestr.col = "NUMERIC"
WHEN dtype == 3 THEN odbc.!fieldtypestr.col = "DECIMAL"
WHEN dtype == 4 THEN odbc.!fieldtypestr.col = "INTEGER"
WHEN dtype == 5 THEN odbc.!fieldtypestr.col = "SMALLINT"
WHEN dtype == 6 THEN odbc.!fieldtypestr.col = "FLOAT"
WHEN dtype == 7 THEN odbc.!fieldtypestr.col = "REAL"
WHEN dtype == 8 THEN odbc.!fieldtypestr.col = "DOUBLE"
WHEN dtype == 9 THEN odbc.!fieldtypestr.col = "DATE"
WHEN dtype == 10 THEN odbc.!fieldtypestr.col = "TIME"
WHEN dtype == 11 THEN odbc.!fieldtypestr.col = "TIMESTAMP"
WHEN dtype == 12 THEN odbc.!fieldtypestr.col = "VARCHAR"
WHEN dtype == -1 THEN odbc.!fieldtypestr.col = "LONGVARCHAR"
WHEN dtype == -2 THEN odbc.!fieldtypestr.col = "BINARY"
WHEN dtype == -3 THEN odbc.!fieldtypestr.col = "VARBINARY"
WHEN dtype == -4 THEN odbc.!fieldtypestr.col = "LONGVARBINARY"
WHEN dtype == -5 THEN odbc.!fieldtypestr.col = "BIGINT"
WHEN dtype == -6 THEN odbc.!fieldtypestr.col = "TINYINT"
WHEN dtype == -7 THEN odbc.!fieldtypestr.col = "BIT"
WHEN dtype == -11 THEN odbc.!fieldtypestr.col = "GUID"
OTHERWISE odbc.!fieldtypestr.col = "UNKNOWN TYPE"
END
odbc.!fieldname.col = LEFT(colname, colnamelen)
odbc.!fieldtypenum.col = dtype
odbc.!fieldsize.col = colsize
odbc.!fielddecdigits.col = DIGITS
odbc.!fieldnullav.col = av
END
RETURN ""
odbcgetrecord: PROCEDURE EXPOSE odbc.
odbcgetrecordagain:
ret = sqlfetch(odbc.!glstmt)
IF ret \== 0 & ret \== 1 THEN DO
column = "Can't fetch the row"
odbcgetrecorderr:
errlen = 0
CALL sqlerror odbc.!glenv, odbc.!gldbc, odbc.!glstmt, STATE, statelen, err, 511, errlen
RETURN odbcprocesserror(column)
END
DO column = 1 TO odbc.!fieldcount
ret = sqlgetdata(odbc.!glstmt, column, 1, data, 255 , len)
IF ret \== 0 THEN DO
column = "Can't get the data for the row"
SIGNAL odbcgetrecorderr
END
IF len \== -1 THEN odbc.!fielddata.column = LEFT(data, len)
ELSE odbc.!fielddata.column = ""
END
RETURN ""
odbcdisconnect: PROCEDURE EXPOSE odbc.
IF SYMBOL('ODBC.!GLSTMT') == 'VAR' THEN DO
ret = sqlfreestmt(odbc.!glstmt, 1 )
IF ret \== 0 THEN DO
errlen = 0
CALL sqlerror odbc.!glenv, odbc.!gldbc, odbc.!glstmt, STATE, statelen, err, 511, errlen
RETURN odbcprocesserror("Can't release the statement handle")
END
DROP odbc.!glstmt
END
IF SYMBOL('ODBC.!CONNECTED') == 'VAR' THEN DO
ret = sqldisconnect(odbc.!gldbc)
IF ret \== 0 THEN DO
errlen = 0
CALL sqlerror odbc.!glenv, odbc.!gldbc, 0, STATE, statelen, err, 511, errlen
RETURN odbcprocesserror("Can't disconnect from the database")
END
DROP odbc.!connected
END
RETURN ""
odbcexit: PROCEDURE EXPOSE odbc.
ret = odbcdisconnect()
IF ret \== "" THEN RETURN sqlret
IF SYMBOL('ODBC.!GLDBC') == 'VAR' THEN DO
ret = sqlfreeconnect(odbc.!gldbc)
IF ret \== 0 THEN DO
errlen = 0
CALL sqlerror odbc.!glenv, odbc.!gldbc, 0, STATE, statelen, err, 511, errlen
RETURN odbcprocesserror("Can't release the database manager")
END
DROP odbc.!gldbc
END
IF SYMBOL('ODBC.!GLENV') == 'VAR' THEN DO
ret = sqlfreeenv(odbc.!glenv)
IF ret \== 0 THEN DO
errlen = 0
CALL sqlerror odbc.!glenv, 0, 0, STATE, statelen, err, 511, errlen
RETURN odbcprocesserror("Can't release the interface")
END
END
DROP odbc.
RETURN ""
odbcgetdsnsupportedlist: PROCEDURE EXPOSE odbc.
DIR = 2
odbc.!supportcount = 0
DO UNTIL ret \== 0
ret = sqldrivers(odbc.!glenv, DIR, descrip, 513 , dlen)
IF ret \== 0 THEN DO
IF ret == 100 THEN LEAVE
errlen = 0
CALL sqlerror 0, 0, 0, STATE, statelen, err, 511 , errlen
RETURN odbcprocesserror("Can't get supported databases list")
END
odbc.!supportcount = odbc.!supportcount + 1
odbc.!support.[odbc.!supportcount] = LEFT(descrip, dlen)
DIR = 1
END
RETURN ""
odbcgetdsnlist: PROCEDURE EXPOSE odbc.
DIR = 2
index = 0
DO UNTIL ret \== 0
ret = sqldatasources(odbc.!glenv, DIR, NAME, 513 , namelen, descrip, 513, descriplen)
IF ret \== 0 THEN DO
IF ret == 100 THEN LEAVE
errlen = 0
CALL sqlerror 0, 0, 0, STATE, statelen, err, 511 , errlen
RETURN odbcprocesserror("Can't get DSN list")
END
index = index + 1
odbc.!dsn.index = LEFT(NAME, namelen)
odbc.!dsndesc.index = LEFT(descrip, descriplen)
DIR = 1
END
odbc.!dsncount = index
RETURN ""
odbcfuncname2id: PROCEDURE
func.1 = "SQLAllocConnect"
func.2 = "SQLAllocEnv"
func.3 = "SQLAllocStmt"
func.4 = "SQLBindCol"
func.5 = "SQLCancel"
func.6 = "SQLColAttributes"
func.7 = "SQLConnect"
func.8 = "SQLDescribeCol"
func.9 = "SQLDisconnect"
func.10 = "SQLError"
func.11 = "SQLExecDirect"
func.12 = "SQLExecute"
func.13 = "SQLFetch"
func.14 = "SQLFreeConnect"
func.15 = "SQLFreeEnv"
func.16 = "SQLFreeStmt"
func.17 = "SQLGetCursorName"
func.18 = "SQLNumResultCols"
func.19 = "SQLPrepare"
func.20 = "SQLRowCount"
func.21 = "SQLSetCursorName"
func.22 = "SQLSetParam"
func.23 = "SQLTransact"
func.40 = "SQLColumns"
func.41 = "SQLDriverConnect"
func.42 = "SQLGetConnectOption"
func.43 = "SQLGetData"
func.44 = "SQLGetFunctions"
func.45 = "SQLGetInfo"
func.46 = "SQLGetStmtOption"
func.47 = "SQLGetTypeInfo"
func.48 = "SQLParamData"
func.49 = "SQLPutData"
func.50 = "SQLSetConnectOption"
func.51 = "SQLSetStmtOption"
func.52 = "SQLSpecialColumns"
func.53 = "SQLStatistics"
func.54 = "SQLTables"
func.55 = "SQLBrowseConnect"
func.56 = "SQLColumnPrivileges"
func.57 = "SQLDataSources"
func.58 = "SQLDescribeParam"
func.59 = "SQLExtendedFetch"
func.60 = "SQLForeignKeys"
func.61 = "SQLMoreResults"
func.62 = "SQLNativeSql"
func.63 = "SQLNumParams"
func.64 = "SQLParamOptions"
func.65 = "SQLPrimaryKeys"
func.66 = "SQLProcedureColumns"
func.67 = "SQLProcedures"
func.68 = "SQLSetPos"
func.69 = "SQLSetScrollOptions"
func.70 = "SQLTablePrivileges"
func.71 = "SQLDrivers"
func.72 = "SQLBindParameter"
func = STRIP(ARG(1))
DO i OVER func.
IF func == func.i THEN RETURN i
END
RETURN ""
odbcfuncissupported: PROCEDURE EXPOSE odbc.
func = STRIP(ARG(1))
ret = odbcfuncname2id(func)
IF ret \== "" THEN DO
ret = sqlgetfunctions(odbc.!gldbc, ret, flag)
IF ret \== 0 THEN DO
errlen = 0
CALL sqlerror odbc.!glenv, odbc.!gldbc, 0, STATE, statelen, err, 511, errlen
RETURN odbcprocesserror("Can't get function information")
END
IF flag THEN RETURN ""
END
RETURN "ODBC ERROR:" func "is not supported"
RETURN ""
odbcprintdriverinfo: PROCEDURE EXPOSE odbc.
func.1 = "SQLAllocConnect"
func.2 = "SQLAllocEnv"
func.3 = "SQLAllocStmt"
func.4 = "SQLBindCol"
func.5 = "SQLCancel"
func.6 = "SQLColAttributes"
func.7 = "SQLConnect"
func.8 = "SQLDescribeCol"
func.9 = "SQLDisconnect"
func.10 = "SQLError"
func.11 = "SQLExecDirect"
func.12 = "SQLExecute"
func.13 = "SQLFetch"
func.14 = "SQLFreeConnect"
func.15 = "SQLFreeEnv"
func.16 = "SQLFreeStmt"
func.17 = "SQLGetCursorName"
func.18 = "SQLNumResultCols"
func.19 = "SQLPrepare"
func.20 = "SQLRowCount"
func.21 = "SQLSetCursorName"
func.22 = "SQLSetParam"
func.23 = "SQLTransact"
func.40 = "SQLColumns"
func.41 = "SQLDriverConnect"
func.42 = "SQLGetConnectOption"
func.43 = "SQLGetData"
func.44 = "SQLGetFunctions"
func.45 = "SQLGetInfo"
func.46 = "SQLGetStmtOption"
func.47 = "SQLGetTypeInfo"
func.48 = "SQLParamData"
func.49 = "SQLPutData"
func.50 = "SQLSetConnectOption"
func.51 = "SQLSetStmtOption"
func.52 = "SQLSpecialColumns"
func.53 = "SQLStatistics"
func.54 = "SQLTables"
func.55 = "SQLBrowseConnect"
func.56 = "SQLColumnPrivileges"
func.57 = "SQLDataSources"
func.58 = "SQLDescribeParam"
func.59 = "SQLExtendedFetch"
func.60 = "SQLForeignKeys"
func.61 = "SQLMoreResults"
func.62 = "SQLNativeSql"
func.63 = "SQLNumParams"
func.64 = "SQLParamOptions"
func.65 = "SQLPrimaryKeys"
func.66 = "SQLProcedureColumns"
func.67 = "SQLProcedures"
func.68 = "SQLSetPos"
func.69 = "SQLSetScrollOptions"
func.70 = "SQLTablePrivileges"
func.71 = "SQLDrivers"
func.72 = "SQLBindParameter"
SAY "------------------" || '0D0A'x || "ODBC API Functions" || '0D0A'x "------------------"
sqlgetallfunctions(odbc.!gldbc, 0 , funcs)
DO i = 1 TO 100
IF SYMBOL("FUNC."||i) == 'VAR' THEN DO
IF funcs.i THEN SAY func.i "is supported"
ELSE SAY func.i "is not supported"
END
END
RETURN ""
|
|