NB. built from project: ~Source\api\odbc\odbc
NB. api

coclass 'jdd'

sqlallochandle=: 'odbc32 SQLAllocHandle s i i *i' &cd
sqlfreehandle=: 'odbc32 SQLFreeHandle s i i' &cd
sqlgetdiagrec=: 'odbc32 SQLGetDiagRec s i i i *c *i *c i *i' &cd
sqlbindcol=: 'odbc32 SQLBindCol s i i i * i *' &cd
sqlfetchscroll=: 'odbc32 SQLFetchScroll s i i i' &cd
sqlconnect=: 'odbc32 SQLConnect s i *c i *c i *c i' &cd
sqlexecdirect=: 'odbc32 SQLExecDirect s i *c i' &cd
sqlnumresultcols=: 'odbc32 SQLNumResultCols s i *i' &cd
sqldescribecol=: 'odbc32 SQLDescribeCol s i i *c i *i *i *i *i *i' &cd
sqlfetch=: 'odbc32 SQLFetch s i' &cd
sqlgetdata=: 'odbc32 SQLGetData s i i i * i *i' &cd
sqldisconnect=: 'odbc32 SQLDisconnect s i' &cd
sqldatasources=: 'odbc32 SQLDataSources s i i *c i *i *c i *i' &cd
sqltables=: 'odbc32 SQLTables s i *c i *c i *c i *c i' &cd
sqlcolumns=: 'odbc32 SQLColumns s i *c i *c i *c i *c i' &cd
sqlrowcount=: 'odbc32 SQLRowCount s i *i' &cd
sqlendtran=: 'odbc32 SQLEndTran s i i i' &cd
sqlsetconnectattr=: 'odbc32 SQLSetConnectAttr s i i i i' &cd
sqlsetstmtattr=: 'odbc32 SQLSetStmtAttr s i i i i' &cd
sqlsetenvattr=: 'odbc32 SQLSetEnvAttr s i i i i' &cd
ISI01=: 'ISI01 Too many connections'  
ISI02=: 'ISI02 Too many statements'   
ISI03=: 'ISI03 Bad connection handle'				
ISI04=: 'ISI04 Bad statement handle'			
ISI05=: 'ISI05 Not a select command'
ISI06=: 'ISI06 Transactions not supported'
ISI07=: 'ISI07 Bad transaction state'
ISI08=: 'ISI08 Bad arguments'         
ISI09=: 'ISI09 Unsupported data type'
ISI10=: 'ISI10 Unable to bind all columns'
ISI11=: 'ISI11 Unable to initialize ODBC environment'
ISI12=: 'ISI12 Unable to set 3.x ODBC version'
ISI13=: 'ISI13 SQL errors fetching row'
SQLST_WARNING=: '01000'
SQL_SUCCESS=: 0
SQL_SUCCESS_WITH_INFO=: 1
SQL_NO_DATA=: 100
SQL_ERROR=: _1
SQL_INVALID_HANDLE=: _2
SQL_STILL_EXECUTING=: 2
SQL_NEED_DATA=: 99
SQL_MAX_DSN_LENGTH=: 32
SQL_COMMIT=: 0
SQL_ROLLBACK=: 1
SQL_NTS=: _3                     
SQL_HANDLE_ENV=: 1
SQL_HANDLE_DBC=: 2
SQL_HANDLE_STMT=: 3
SQL_HANDLE_DESC=: 4
SQL_FETCH_NEXT=: 1
SQL_FETCH_FIRST=: 2
SQL_ATTR_ODBC_VERSION=: 200
SQL_OV_ODBC3=: 3
SQL_ATTR_ROW_BIND_TYPE=: 5       
SQL_BIND_BY_COLUMN=: 0           
SQL_ATTR_ROWS_FETCHED_PTR=: 26
SQL_ATTR_ROW_ARRAY_SIZE=: 27
SQL_ATTR_ROW_STATUS_PTR=: 25	
SQL_ATTR_AUTOCOMMIT=: 102        
SQL_AUTOCOMMIT_OFF=: 0           
SQL_ROWSET_SIZE=: 9
SQL_IS_UINTEGER=: _5
COLUMNBUF=: 1000     
LONGBUF=: 5000       
SHORTBUF=: 255       


char_trctnb=: ]`trctnb @. (2:=3!:0)
trctnb=: <:@{:@$ {."1 (i.&({.a.) {. ])"1
trbuclnb=: (] i.&> ({.a.)"_) {.&.> ]
rebtbcol=: ] #"1~ [: -. [: *./ [: *./\."1 ' '&=
trctnob=: [: rebtbcol ] -."1 (0{a.)"_
trctguid=: 36&{."1

b0=: <"0
bs=: ];#
fat=: ''&$@:,
tolower=: 3 : '(y.i.~''ABCDEFGHIJKLMNOPQRSTUVWXYZ'',a.){''abcdefghijklmnopqrstuvwxyz'',a.'
alltrim=: ] #~ [: -. [: (*./\. +. *./\) ' '&=
src=: _1: ic 1: ic ]
sqlbad=: 13 : '(src >{. y.) e. DD_ERROR'
sqlok=: 13 : '(src >{. y.) e. DD_SUCCESS'
iscl=: 2&=@(3!:0) *. 1: >: [: # $
isua=: 0: = [: # $
isiu=: 3!:0 e. 1 4"_
isia=: isua *. isiu
ifs=: [: ,. [: _1&ic ,
ffs=: [: ,. [: _1&fc ,
dts=: 13 : '((#y.),6) $ _1&ic , 12{."1 y.'
fmterr=: [: ; ([: ":&.> ]) ,&.> ' '"_
badrow=: 13 : '0 e. (src ;{.&> y.) e. DD_SUCCESS'


bindcol=: 4 : 0"1 1
'sh col rows'=. y.
'type precision'=. x.
type=. fat src type

name=. (":sh),'_',":col
bname=. 'BIND_',name
blname=. 'BINDLN_',name
(blname)=: (rows,1)$2-2
if. type e. SQL_CHAR,SQL_VARCHAR,SQL_DECIMAL,SQL_NUMERIC do.
  len=. fat >:precision [ tartype=. SQL_DEFAULT
  (bname)=: (rows,len)$' '
elseif. type e. SQL_BINARY,SQL_VARBINARY do.
  len=. fat >:precision [ tartype=. SQL_CHAR
  (bname)=: (rows,len)$' '
elseif. type e. SQL_INTEGER do.
  len=. 4 [ tartype=. SQL_DEFAULT
  (bname)=: (rows,1)$2-2
elseif. type e. SQL_SMALLINT do.
  len=. 2 [ tartype=. SQL_DEFAULT
  (bname)=: (rows,len)$' '
elseif. type e. SQL_TYPE_TIMESTAMP do.
  len=. 16 [ tartype=. SQL_DEFAULT
  (bname)=: (rows,len)$' '
elseif. type e. SQL_WCHAR,SQL_WVARCHAR do.  
  len=. fat >: +: precision [ tartype=. SQL_CHAR
  (bname)=: (rows,len)$' '
elseif. type e. SQL_DOUBLE,SQL_FLOAT do.
  len=. 8 [ tartype=. SQL_DEFAULT
  (bname)=: (rows,1)$2.5-2.5
elseif. type e. SQL_REAL do.
  len=. 4 [ tartype=. SQL_DEFAULT
  (bname)=: (rows,len)$' '
elseif. type e. SQL_BIT,SQL_TINYINT do.
  len=. 1 [ tartype=. SQL_DEFAULT
  (bname)=: (rows,len)$' '
elseif. type e. SQL_UNIQUEID do.
  len=. 37 [ tartype=. SQL_CHAR
  (bname)=: (rows,len)$' '
elseif.do. SQL_ERROR return.
end.

sqlbindcol sh;col;tartype;(vad bname);len;<vad blname
)
DD_SUCCESS=: SQL_SUCCESS,SQL_SUCCESS_WITH_INFO
DD_ERROR=: SQL_ERROR,SQL_INVALID_HANDLE
DD_OK=: 0

fmtdts=: 3 : 0
d=. dts y.
b=. ({:"1 d ) <: 60 
s=. $d=. (4,5#3) ": b *"0 1 d
d=. , d
d=. s$'0'(I. ' '=d)}d
d=. ((#d)#,:'-- ::') (<a:;4 7 10 13 16)} d
(b * {:$d) {."0 1 d
)

errret=: 3 : 0
r=. SQL_ERROR
LERR=: ''
ALLDM=: i. 0 0
if. iscl y. do.
  LERR=: y.
else.
  't h'=. y.
  if. SQL_ERROR-:em=. t getlasterror h do. r return.
  elseif. c=. #em do.
    LERR=: fmterr {. em   
    ALLDM=: em             
    if. 1<c do. LERR=: LERR , ' - more error info available (1)' end.
  end.
end.
r
)

clr=: 3 : 0
LERR=: ''
ALLDM=: i. 0 0
)

ddsrc=: 3 : 0  
clr 0
d=. EH;SQL_FETCH_FIRST
n=. EH;SQL_FETCH_NEXT
l=. >:SQL_MAX_DSN_LENGTH
r=. i.0 0

while.do.
  
  z=. sqldatasources d ,(l#' ');256;(,0);(256#' ');256;,0
  
  if. sqlbad z do. errret '' return. end.
  
  if. SQL_NO_DATA=rc=. src >0{z do. break. end.
  
  if. -. sqlok rc do. errret '' return. end.
  d=. n
  r=. r , 3 6{z
  
end.
trbuclnb r
)

ddtbl=: 3 : 0  
clr 0
if. -. isia y. do. errret ISI08 return. end.
if. -. y. e. CHALL do. errret ISI03 return. end.
if. SQL_ERROR=sh=. getstmt y. do. errret '' return. end.
z=. sqltables sh;(<0);256;(<0);256;(<0);256;(<0);256
if. sqlok z do.
  
  CSPALL=: CSPALL,y.,sh
  sh
else.
  r=. errret SQL_HANDLE_STMT,sh
  r [ freestmt sh return.
end.
)

ddtblx=: 3 : 0  
if. SQL_ERROR-:sh=. ddtbl y. do. SQL_ERROR
elseif. SQL_ERROR-:dat=. ddfch sh,_1 do. SQL_ERROR
elseif. 0<>./ #&> dat do. trctnob@:":&.> dat
elseif.do. dat
end.
)
ddcheck=: 3 : 0
if. _1=y. do. wdinfo 'Data Driver';dderr $0 else. y. end.
)
ddcol=: 4 : 0  
clr 0
y=. y.
if. -. (iscl x.) *. isia y=. fat y do. errret ISI08 return. end.
if. -. y e. CHALL do. errret ISI03 return. end.
if. SQL_ERROR=sh=. getstmt y do. errret '' return. end.
z=. sqlcolumns sh;(<0);256;(<0);256;x.;SQL_NTS;(<0);256
if. sqlbad z do.
  r=. errret SQL_HANDLE_STMT,sh
  r [ freestmt sh return.
end.
r=. getcoldefs sh
r [ freestmt sh
)

getlasterror=: 3 : 0
(EH;CHALL;1{"1 CSPALL) getlasterror y.
:
if. 0=L. x. do.
  t=. fat x.
else.
  b=. >(<y.) e. each x.
  if. 1~:+/b do. SQL_ERROR return. end.
  t=. fat b#SQL_HANDLE_ENV,SQL_HANDLE_DBC,SQL_HANDLE_STMT
end.
r=. 0 3$''
while.do.
  z=. sqlgetdiagrec t;y.;(1+0{$r);(5#' ');(,0);(256#' ');256;,0
  if. sqlbad z do. SQL_ERROR return. end.
  if. SQL_NO_DATA=src >0{z do. break. end.
  r=. r,(2{.4}.z),<(>8{z){.>6{z
end.
r
)

getstmt=: 3 : 0
z=. sqlallochandle SQL_HANDLE_STMT;({.y.);,0
if. sqlbad z do. SQL_ERROR else. fat >3{z end.
)

freestmt=: 3 : 0
sqlfreehandle SQL_HANDLE_STMT;y.
)

freeenv=: 3 : 0
sqlfreehandle SQL_HANDLE_ENV;y.
)

gc=: 0 4 6&{  
tdatchar=: 3 : 0"1
sqlgetdata (b0 y.),SQL_CHAR;(SHORTBUF$' ');(>:SHORTBUF);,0
)

trimdat=: 13 : '(<(>2{y.){.>1{y.) 1} y.'
datchar=: 3 : 0"1
z=. gc sqlgetdata (b0 y.),SQL_CHAR;(SHORTBUF$' ');(>:SHORTBUF);,0
if. sqlok z do. trimdat z else. z end.
)
datwchar=: 3 : 0"1
bufln=. >:buf=. 2*SHORTBUF
z=. gc sqlgetdata (b0 y.),SQL_CHAR;(buf$' ');bufln;,0
if. sqlok z do. trimdat z else. z end.
)
datdouble=: 3 : 0"1
gc sqlgetdata (b0 y.),SQL_DOUBLE;(,1.5-1.5);8;,0
)
datinteger=: 3 : 0"1
gc sqlgetdata (b0 y.),SQL_INTEGER;(,256);4;,0
)
datsmallint=: 3 : 0"1
z=. gc sqlgetdata (b0 y.),SQL_SMALLINT;(2$' ');3;,0
if. sqlok z do.
  (<fat _1&ic >1{z) 1} z
else.
  z
end.
)
datbit=: 3 : 0"1
gc sqlgetdata (b0 y.),SQL_DEFAULT;(1$' ');1;,0
)
datreal=: 3 : 0"1
z=. gc sqlgetdata (b0 y.),SQL_CHAR;(4$' ');4;,0
if. sqlok z do.
  (<fat _1&fc >1{z) 1} z
else.
  z
end.
)
dattimestamp=: 3 : 0"1
z=. gc sqlgetdata (b0 y.),SQL_DEFAULT;(16$' ');17;,0
if. sqlok z do.
  (<,fmtdts ,:>1{z) 1}z
else.
  z
end.
)
datlong=: 3 : 0"1
sc=. b0 y.
get=. sc,SQL_BINARY;(LONGBUF$' ');LONGBUF;,0

z=. sqlgetdata get
lim=. >{:z  
dat=. ''
while. lim>:#dat do.
  if. sqlbad rc=. >{. z do. SQL_ERROR;'';0 return. end.
  if. SQL_NO_DATA=src rc do. break. end.
  
  dat=. dat , (LONGBUF<.>{:z) {. , >4{z
  z=. sqlgetdata get
end.
DD_OK ; dat ; #dat  
)
getchar=: datchar&.>
getwchar=: datwchar&.>
getbinary=: datchar&.>
getvarbinary=: datchar&.>
getbit=: datbit&.>
getdecimal=: datchar&.>
getnumeric=: datchar&.>
getbigint=: datchar&.>
getdouble=: datdouble&.>
getfloat=: datdouble&.>
getreal=: datreal&.>         
getvarchar=: datchar&.>
getwvarchar=: datchar&.>
getinteger=: datinteger&.>
getsmallint=: datsmallint&.>
gettinyint=: datbit&.>
getlongvarchar=: datlong&.>
getlongvarbinary=: datlong&.>
getwlongvarchar=: datlong&.>
gettype_timestamp=: dattimestamp&.>
getuniqueid=: datchar&.>

iad=: 3 : 0
ple=. 15!:6 <y.        
pa=. memr ple,4,1,4    
''$pa+memr pa,0,1,4    
)

vad=: <@:iad  

getcolinfo=: 3 : 0"1
arg=. (b0 y.),(bs 128$' '),5#<,0
sqldescribecol arg
)

getallcolinfo=: 3 : 0
if. sqlbad z=. sqlnumresultcols y.;,0 do.
  SQL_ERROR
else.
  z=. getcolinfo y.,.1+i.>2{z
  
  z=. (<"0 src;6{"1 z)(<a:;6)}z
end.
)

ddcon=: 3 : 0  
f=. (i.&';')({. ; }.@}.) ]
clr 0
if. -.iscl y. do. errret ISI08 return. end.
if. -.'dsn=' -: tolower 4{.y. do. errret ISI08 return. end.
dsn=. uid=. pwd=. ''

txt=. <;._2 y., ';' -. {:y.
ndx=. txt i.&> '='
nms=. tolower each ndx {.each txt
vls=. (ndx+1) }.each txt
(nms)=. vls
z=. sqlallochandle SQL_HANDLE_DBC;EH;,0
if. sqlbad z do. errret SQL_HANDLE_ENV,EH return. end.

HDBC=: fat >3{z

z=. sqlconnect LASTCONNECT=: HDBC;(bs dsn),(bs uid),bs pwd
if. sqlbad z do. errret SQL_HANDLE_DBC,HDBC return. end.
if. SQL_ERROR-:em=. SQL_HANDLE_DBC getlasterror HDBC do. errret '' return.
elseif. #em do.
  if. 0&e. ({."1 em) e. <SQLST_WARNING do.
    errret fmterr {.em return.
  end.
end.

CHALL=: CHALL,HDBC
HDBC
)

dddis=: 3 : 0"0   
clr 0
y=. y.
if. -.isia y=. fat y do. errret ISI08 return. end.
if. -. y e. CHALL do. errret ISI03 return. end.
ddend 1{"1 CSPALL#~y=0{"1 CSPALL
ch=. y 
if. sqlbad sqldisconnect y do. errret SQL_HANDLE_DBC,ch return. end.
if. sqlbad sqlfreehandle SQL_HANDLE_DBC;y. do. errret '' return. end.
CHALL=: CHALL-.ch
CSPALL=: CSPALL#~ch~:0{"1 CSPALL
DD_OK
)

ddsel=: 4 : 0  
clr 0
if. -.(isia y=. fat y.) *. iscl x. do. errret ISI08 return. end.
if. -.y e. CHALL do. errret ISI03 return. end.
if. SQL_ERROR=sh=. getstmt y do. errret SQL_HANDLE_DBC,y return. end.
if. sqlok sqlexecdirect sh;bs x. do.
  sh [ CSPALL=: CSPALL,y,sh
else.
  r=. errret SQL_HANDLE_STMT,sh
  r [ freestmt sh
end.
)
transact=: 4 : 0
if. sqlok sqlendtran SQL_HANDLE_DBC;y.;x. do.
  DD_OK [ CHTR=: CHTR-.y.
else.
  SQL_ERROR
end.
)

ddsql=: 4 : 0  
clr DDROWCNT=: 0
if. -.(isia y.) *. iscl x. do. errret ISI08 return. end.
if. -.y.e.CHALL do. errret ISI03 return. end.
if. SQL_ERROR=sh=. getstmt y. do. errret SQL_HANDLE_DBC,y. return. end.
if. sqlok sqlexecdirect sh;bs x. do.
  
  if. sqlok z=. sqlrowcount sh;,256 do. DDROWCNT=: fat >{:z end.
  
  if. -. y. e. CHTR do. SQL_COMMIT transact y. end.
  DD_OK [ freestmt sh
else.
  r=. errret SQL_HANDLE_STMT,sh
  r [ freestmt sh
end.
)

ddcnt=: 3 : 0  
DDROWCNT
)

ddend=: 3 : 0"0  
clr 0
y=. y.
if. -.isia y=. fat y do. errret ISI08 return. end.
if. -.y e.1{"1 CSPALL do. errret ISI04 return. end.
sh=. y
z=. sqlfreehandle SQL_HANDLE_STMT;y
CSPALL=: CSPALL#~sh~:1{"1 CSPALL
erasebind sh
if. sqlbad z do. errret SQL_HANDLE_STMT,sh else. DD_OK end.
)
ddfch=: 3 : 0
COLUMNBUF ddfch y.
:
clr 0
if. -.(isia x.) *. isiu y. do. errret ISI08 return. end.
'sh r'=. 2{.,y.,1
if. -.sh e.1{"1 CSPALL do. errret ISI04 return. end.
r=. (r<0){r,_1  
if. SQL_ERROR-:ci=. getallcolinfo sh do. errret '' return. end.
buf=. (_1=r){r,x.
if. sqlbad z=. ci dbind sh,buf do. SQL_ERROR return. end.
cv=. GCNM {~ GDX i. ; 6 {"1 ci

one=. 0<r
dat=. (#ci)#<i.0 0
if. r=0 do. dat return. end.
fetch=. sh;SQL_FETCH_NEXT;0
while.do.
  
  rc=. >{.sqlfetchscroll fetch
  if. sqlbad rc do. errret SQL_HANDLE_STMT,sh return. end.
  if. SQL_NO_DATA=src rc do. ddend sh break. end.
  
  c=. dddcnt sh
  
  z=. ''
  for_i. i.#ci do.
    n=. (i_index{cv) `:0 dddata sh,i+1
    
    
    if. _1 e. len=. dddataln sh,i+1 do.
      ndx=. I. len = _1
      if. 2 = 3!:0 n do.
        n=. ' ' ndx } n
      else.
        n=. __ ndx } n
      end.
    end.
    z=. z,< n
  end.
  if. c<buf do. z=. (fat c) {.&.> z end.
  
  dat=. dat ,&.> z
  if. one do. if. c<buf do. ddend sh end. break. end.
end.
dat
)

ddbind=: 3 : 0  
COLUMNBUF ddbind y. 
:
clr 0
if. -.(isia x.) *. isiu y. do. errret ISI08 return. end.
'sh r'=. 2{.,y.,x.
if. -.sh e.1{"1 CSPALL do. errret ISI04 return. end.
if. SQL_ERROR-:ci=. getallcolinfo sh do. errret ''
elseif. sqlbad ci dbind sh,r do. SQL_ERROR
elseif.do. DD_OK [ ('BINDTI_',":sh)=: ci  
end.
)

dbind=: 4 : 0
if. 0&e. b=. (;6{"1 x.) e. SQL_COLBIND_TYPES do. errret ISI10 typeerr (-.b)#x. return. end.
dcolbind y.
z=. (6 7{"1 x.) bindcol (0{y.),.(>: i.#x.),.1{y.
if. *./(src ; 0{"1 z) e. DD_SUCCESS do. DD_OK else. errret ISI10 end.
)

ddfetch=: 3 : 0  
y=. y.
if. -.isia y=. fat y do. errret ISI08 return. end.
if. -.y e.1{"1 CSPALL do. errret ISI04 return. end.
if. sqlok sqlfetchscroll y;SQL_FETCH_NEXT;0 do. DD_OK else. errret SQL_HANDLE_STMT,y end.
)

typeerr=: 4 : 0
hd=. ;:'ColNumber ColName TypeCode SqlType'
dat=. 2 3 6 {"1 y.
sqltypes=. (}.SQL_SUPPORTED_NAMES) , '**JDD UNKNOWN TYPE**'
tnames=. <"1 sqltypes {~ SQL_SUPPORTED_TYPES i. ; {:"1 dat
BADTYPES=: hd , (trbuclnb ":&.> dat) ,. alltrim&.> tnames
x. ,' - more error info available (2)'
)

dddata=: 3 : 0  
".'BIND_',(":0{y.),'_',":1{y.
)
dddataln=: 3 : 0
,".'BINDLN_',(":0{y.),'_',":1{y.
)

dddcnt=: 3 : 0
".'BINDRR_',":y.
)
ddrow=: dddcnt 

initodbcenv=: 3 : 0
CHTR=: CHALL=: i.0   
CSPALL=: 0 2$0      
LERR=: ''           
ALLDM=: i. 0 3      
BADTYPES=: i. 0 0   
DDROWCNT=: 0        
z=. sqlallochandle SQL_HANDLE_ENV;0;,0
EH=: fat >3{z
if. sqlbad z do.
  
  wdinfo dderr errret ISI11
  return.
end.
if. sqlbad sqlsetenvattr EH;SQL_ATTR_ODBC_VERSION;SQL_OV_ODBC3;0 do.
  wdinfo dderr errret ISI12
  return.
end.
6!:3[0

DD_OK
)

getcoldefs=: 3 : 0
if. SQL_ERROR-:ci=. getallcolinfo y. do. SQL_ERROR return. end.

ty=. ; 6 {"1 ci  
if. -.*./ ty e. SQL_SUPPORTED_TYPES do. errret ISI09 return. end.
b=. -. ty e. SQL_CHAR,SQL_VARCHAR,SQL_WCHAR,SQL_WVARCHAR

c=. >:i.#ci
dc=. i. 0 0
tr=. 0

z=. sqlfetch y.
while.do.
  if. sqlbad rc=. >{.z do. errret '' return. end.
  if. SQL_NO_DATA=src rc do. break. end.
  
  dc=. dc , tdatchar y. ,. c
  tr=. >:tr
  
  z=. sqlfetch y.
end.

if. 0=#dc do.
  trbuclnb 3 {"1 ci
else.
  dc=. (tr,#b)$alltrim&.>trbuclnb,4{"1 dc
  dc=. (0 ".&.> b #"1 dc) (<a:;I. b)} dc
  (trbuclnb 3 {"1 ci) , dc
end.

)

endodbcenv=: 3 : 0
set=. 0&= @: (4!:0)
if. set <'CHTR' do. if. #CHTR do. ddrbk CHTR end. end.
if. set <'CSPALL' do. if. #CSPALL do. ddend {:"1 CSPALL end. end.
if. set <'CHALL' do. dddis CHALL end.
if. set <'EH' do. freeenv EH end.  
erase ;:'CSPALL CHALL EH'
)

ddcnm=: 3 : 0  
clr 0
y=. y.
if. -. isia y=. fat y do. errret ISI08 return. end.
if. -.y e.1{"1 CSPALL do. errret ISI04 return. end.
if. SQL_ERROR-:ci=. getallcolinfo y do. errret SQL_HANDLE_STMT,y return. end.
trbuclnb 3{"1 ci
)

dderr=: 3 : 0  
0 dderr y.
:
select. x.
case. 1 do. ALLDM
case. 2 do. BADTYPES
case.do. LERR
end.
)

ddtrn=: 3 : 0  
clr 0
y=. fat y.
if. -. isia y=. fat y do. errret ISI08 return. end.
if. -. y e. CHALL do. errret ISI03 return. end.
if. y e. CHTR do. errret ISI07 return. end.

if. sqlok sqlsetconnectattr y;SQL_ATTR_AUTOCOMMIT;SQL_AUTOCOMMIT_OFF;SQL_IS_UINTEGER do.
  DD_OK [ CHTR=: CHTR,y
else.
  errret SQL_HANDLE_DBC,y
end.
)

comrbk=: 4 : 0
clr 0
y=. y.
if. -. isia y=. fat y do. errret ISI08 return. end.
if. -. y e. CHALL do. errret ISI03 return. end.
if. -. y e. CHTR do. errret ISI07 return. end.
if. sqlok x. transact y do. DD_OK else. errret SQL_HANDLE_DBC,y end.
)

ddcom=: 3 : 0  
SQL_COMMIT comrbk y.
)

ddrbk=: 3 : 0  
SQL_ROLLBACK comrbk y.
)

erasebind=: 3 : 0"0
if. b=. #n=. 'B' (4!:1) 0 do. *./(4!:55) n #~ +./"1 (,:'_',":,y.) E. > n else. b end.
)

dcolbind=: 3 : 0
'sh r'=. y.
bstname=. 'BINDST_',":sh
(bstname)=: (r,2)$' '
brfname=. 'BINDRR_',":sh
(brfname)=: ,256
et=. SQL_HANDLE_STMT,sh
if. sqlbad sqlsetstmtattr sh;SQL_ATTR_ROW_BIND_TYPE;SQL_BIND_BY_COLUMN;0 do. errret et
elseif. sqlbad sqlsetstmtattr sh;SQL_ATTR_ROW_ARRAY_SIZE;r;0 do. errret et
elseif. sqlbad sqlsetstmtattr sh;SQL_ATTR_ROW_STATUS_PTR;(iad bstname);0 do. errret et
elseif. sqlbad sqlsetstmtattr sh;SQL_ATTR_ROWS_FETCHED_PTR;(iad brfname);0 do. errret et
elseif.do. DD_OK
end.
)

setzface=: 3 : 0
r=. i. 0 0
if. (<'base') -: cl=. 18!:5 '' do. r
else.
  cl=. '_' , (,>cl) , '_'
  wrds=. 'ddsrc ddtbl ddtblx ddcol ddcon dddis ddfch ddend ddsel ddcnm dderr'
  wrds=. wrds, ' ddsql ddcnt ddtrn ddcom ddrbk ddbind ddfetch'
  wrds=. >;: wrds ,' dddata ddfet ddbtype ddcheck ddrow'
  ". (wrds ,"1 '_z_ =: ',"1 wrds ,"1 cl) -."1 ' '
  r
end.
)

ddfet=: 3 : 0  
clr 0
if. -. isiu y. do. errret ISI08 return. end.
'sh r'=. 2{.,y.,1
if. -. sh e.1{"1 CSPALL do. errret ISI04 return. end.
r=. (r<0){r,_1  
if. SQL_ERROR-:ci=. getallcolinfo sh do.
  errret ''
else.
  ci getdata sh,r
end.
)

ddbtype=: 3 : 0
".'BINDTI_',":y.
)

getdata=: 4 : 0
'sh r'=. y.
ty=. ; 6 {"1 x.
if. -.*./b=. ty e. SQL_SUPPORTED_TYPES do. errret ISI09 typeerr (-.b)#x. return. end.
gf=. (SQL_SUPPORTED_TYPES i. ty){GGETV
cc=. <"1 sh,.>:i.#ty

dat=. i. 0 0
if. r=0 do. dat return. end.

z=. sqlfetch sh
while.do.
  
  if. sqlbad rc=. >{.z do.
    errret SQL_HANDLE_STMT,sh return.
  end.
  if. SQL_NO_DATA=src rc do.
    ddend sh break.
  end.
  
  row=. , 1 gf\cc
  if. badrow row do.
    errret ISI13 return.
  end.
  dat=. dat , 1 {&> row
  
  if. 0=r=. <:r do. break. end.  
  z=. sqlfetch sh
end.
dat
)

SQL_SUPPORTED_NAMES=: (];._2) 0 : 0
0 
SQL_CHAR=: 1['*'           
SQL_NUMERIC=: 2['*'        
SQL_DECIMAL=: 3['*'        
SQL_INTEGER=: 4['*'        
SQL_SMALLINT=: 5['*'       
SQL_FLOAT=: 6['*'          
SQL_REAL=: 7['*'           
SQL_DOUBLE=: 8['*'         
SQL_TYPE_TIMESTAMP=:93['*' 
SQL_VARCHAR=: 12['*'       
SQL_DEFAULT=: 99['*'       
SQL_LONGVARCHAR=: _1       
SQL_BINARY=: _2['*'        
SQL_VARBINARY=: _3['*'     
SQL_LONGVARBINARY=:_4      
SQL_BIGINT=: _5['*'        
SQL_TINYINT=: _6['*'       
SQL_BIT=: _7['*'           
SQL_WCHAR=: _8['*'         
SQL_WVARCHAR=: _9['*'      
SQL_WLONGVARCHAR=: _10     
SQL_UNIQUEID=:_11['*'      
)
settypeinfo=: 3 : 0
sqlnames=. }. SQL_SUPPORTED_NAMES
SQL_SUPPORTED_TYPES=: , ". sqlnames
GDX=: SQL_SMALLINT, SQL_VARCHAR, SQL_CHAR, SQL_TYPE_TIMESTAMP
GCNM=: ;:'ifs           trctnb       trctnb     fmtdts'
GDX=: GDX, SQL_REAL, SQL_WCHAR, SQL_WVARCHAR, SQL_UNIQUEID
GCNM=: GCNM,;:'ffs     trctnb     trctnb        trctguid   char_trctnb'
GGETV=: (sqlnames i."1'=') {."0 1 sqlnames
GGETV=: alltrim&.> <"1 'get',"1 tolower 4 }."1 GGETV
SQL_COLBIND_TYPES=: ('*' +./"1 . = sqlnames) # SQL_SUPPORTED_TYPES
)

settypeinfo 0       
setzface 0          
initodbcenv endodbcenv 0