## In terminal, outside of R
## 
##   cd ~/git/orch/src/misc
##   R CMD SHLIB debugging_odbc.c




library(RODBC)
library(inline)
library(colorout)

# check_thisHandle <- cfunction(c(chan = "SEXP", id = "SEXP", include="~/git/orch/src/misc/debugging_odbc.h"),
# '// check_thisHandle(SEXP chan, SEXP id)
# {
#     SEXP ptr = getAttrib(chan, install("handle_ptr"));
#     pRODBCHandle thisHandle = R_ExternalPtrAddr(ptr);
# 
#     return ScalarLogical(thisHandle);
# }')
# 
# 
# check_ptrType <- cfunction(c(chan = "SEXP", id = "SEXP", include="~/git/orch/src/misc/debugging_odbc.h"),
# '// check_ptrType(SEXP chan, SEXP id)
# {
#     SEXP ptr = getAttrib(chan, install("handle_ptr"));
#     pRODBCHandle thisHandle = R_ExternalPtrAddr(ptr);
# 
#     return ScalarLogical(TYPEOF(ptr) == EXTPTRSXP);
# }')
# 
# 
# check_thisHandle_channel <- cfunction(c(chan = "SEXP", id = "SEXP", include="~/git/orch/src/misc/debugging_odbc.h"),
# '// check_thisHandle_channel(SEXP chan, SEXP id)
# {
#     SEXP ptr = getAttrib(chan, install("handle_ptr"));
#     pRODBCHandle thisHandle = R_ExternalPtrAddr(ptr);
# 
#     return ScalarLogical(thisHandle->channel == asInteger(chan));
# }')
# 
# 
# check_thisHandle_id <- cfunction(c(chan = "SEXP", id = "SEXP", include="~/git/orch/src/misc/debugging_odbc.h"),
# '// check_thisHandle_id(SEXP chan, SEXP id)
# {
#     SEXP ptr = getAttrib(chan, install("handle_ptr"));
#     pRODBCHandle thisHandle = R_ExternalPtrAddr(ptr);
# 
#     return ScalarLogical(thisHandle->id == asInteger(id));
# }')
# 



wh <- "SCIENCE"
dbname <- "prod"
schema <- "production"

sfCon <- sfGetCon(wh=wh, dbname=dbname, schema=schema)
i <- 0
ret <- TRUE

while (!isConExpired(sfCon) && i < 1000 && !isErr(ret)) {
  cat ("attempt ", i, "\n")
  i <- i + 1
  ret <- try(setSnowflake(wh=wh, dbname=dbname, schema=schema, connex=sfCon, verbose=FLASE))
}


dyn.load("debugging_odbc.so")


print(.Call(RODBC:::C_RODBCcheckchannel, sfCon, attr(sfCon, "id")))
print(.C("check_thisHandle"           , sfCon, attr(sfCon, "id")))
print(.C("check_ptrType"              , sfCon, attr(sfCon, "id")))
print(.C("check_thisHandle_channel"   , sfCon, attr(sfCon, "id")))
print(.C("check_thisHandle_id"        , sfCon, attr(sfCon, "id")))



#  I am testing a new database system using a provided ODBC driver and the `RODBC` package. 
#  
#  The issue I am encountering is that after only a few queries (all within the span of 2~3 minutes or less), the connection is no longer recognized as valid by R.
#  
#  Specifically, it is a single C function in the RODBC package, `RODBCcheckchannel` which is complaining. 
#  
#  The first line of `RODBC::sqlQuery` calls 
#  
#      if (!odbcValidChannel(channel))
#          stop("first argument is not an open RODBC channel")
#  
#  `odbcValidChannel` checks three properties of `channel`.  I can confirm that the two checks done in `R` return `TRUE`.  
#  It is the last check, `.Call(RODBC:::C_RODBCcheckchannel, channel, attr(channel, "id"))` which returns `0`
#  
#  Source code for `RODBCcheckchannel` is as follows
#  
#      SEXP RODBCcheckchannel(SEXP chan, SEXP id)
#      {
#          SEXP ptr = getAttrib(chan, install("handle_ptr"));
#          pRODBCHandle thisHandle = R_ExternalPtrAddr(ptr);
#  
#          return ScalarLogical(thisHandle && TYPEOF(ptr) == EXTPTRSXP &&
#             thisHandle->channel == asInteger(chan) &&
#             thisHandle->id == asInteger(id));
#      }
#  
#  I have tried using `R -d valgrind `, but since the C code is not crashing per-se, this was not helpful. 
#  
#  Can someone shed some light as to why `.Call(RODBC:::C_RODBCcheckchannel, channel, attr(channel, "id"))` returns `TRUE` for a short while then returns `FALSE`?  Does it have something to do with the handle? 
#  
#  _(Apologies for the lack of reproducible exmample, as that would require access to a very specific database system)_
