Search code examples
c++rdfunixodbcvirtuosoredland

Connecting Redland to Virtuoso through Virtuoso's ODBC/iODBC on MacOS X Environment


In order to install Virtuoso on my MacOS X environment, i used the brew port, that is:

brew install virtuoso

By doing so, it automatically installed some ODBC/iODBC drivers, that could not be overwritte by any other unixodbc setup. In particular if I try to link such library:

$ brew link unixodbc
Linking /usr/local/Cellar/unixodbc/2.3.4...
Error: Could not symlink bin/isql
Target /usr/local/bin/isql
is a symlink belonging to virtuoso. You can unlink it:
  brew unlink virtuoso

To force the link and overwrite all conflicting files:
  brew link --overwrite unixodbc

To list all files that would be deleted:
  brew link --overwrite --dry-run unixodbc

By the way, I do not want to unlink this version. So I tried to compile Redland from scratch and download it from GitHub. In particular, I used two possible configurations:

env PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./configure --with-virtuoso --with-odbc=/usr/local/Cellar/virtuoso/7.2.4.2
env PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./configure --with-virtuoso --with-iodbc=/usr/local/Cellar/virtuoso/7.2.4.2

After adding rdf_hash_internal.h and rdf_heuristics.h in my project manually, everything just goes smoothly and everything gets both compiled and linked. In my C++ app, I'm trying to access the database with the following code:

world = librdf_new_world();
librdf_world_open(world);
storage = librdf_new_storage(world,"virtuoso",graphName.c_str(),"dsn='Local Virtuoso',user='dba',password='dba'");
model = librdf_new_model(world,storage,NULL);
context_node = librdf_new_node_from_uri_string(world,(const unsigned char*)defaultContext.c_str());
/* librdf_model_transaction_commit(this->super->model) */
librdf_model_size(super->model)

If either I disable the transaction or not, anyway I got the following error at line 941 of "rdf_storage_virtuoso.c":

rc = SQLDriverConnect(connection->hdbc, 0,(UCHAR *) context->conn_str,
                      SQL_NTS, context->outdsn,
                      LIBRDF_VIRTUOSO_CONTEXT_DSN_SIZE,
                      &buflen, SQL_DRIVER_COMPLETE);

Hence, I suppose there is a connection error at the ODBC/iODBC level. By the way, I could connect to virtuoso with the following command:

$ isql localhost:1111 dba dba
Connected to OpenLink Virtuoso
Driver: 07.20.3217 OpenLink Virtuoso ODBC Driver
OpenLink Interactive SQL (Virtuoso), version 0.9849b.
Type HELP; for help and EXIT; to exit.
SQL>

Is there any way to connect the Redland library with ODBC library by Virtuoso? Thanks in advance.


Solution

  • All those troubles were due to a configuration issue that AFIK was described in no guide (Correct me if I'm wrong, I'd like to find more details on both Virtuoso and Redland/librdf). Hereby, as I told in the comments, the problem was in ODBC, but the reason was that there is no mention in no Virtuoso guide how to configure their driver. This is the way to go:

    /Library/ODBC/odbc.ini

    [ODBC Data Sources]
    VOS = virtuoso-odbc
    
    [VOS]
    Driver = /usr/local/Cellar/virtuoso/7.2.4.2/lib/virtodbc.so
    Description = Virtuoso Open-Source Edition
    Address = localhost:1111
    UserName    = dba
    User        = dba
    

    /Library/ODBC/odbcinst.ini

    [ODBC Drivers]
    virtuoso-odbc = Installed
    
    [virtuoso-odbc]
    Driver = /usr/local/Cellar/virtuoso/7.2.4.2/lib/virtodbc.so
    

    Consequently, even the configuration parameters required to access through Redland has to change.

    storage=librdf_new_storage(world, "virtuoso","db1","dsn='VOS',user='dba',password='dba'");
    

    Where VOS is the configuration definition within ODBC. Moreover, the specific ContextNode specifies which is the Named Graph to be used.