Re: DBI-Users RE: DBD-Oracle - obtaining OCI handles from $dbh
I'm late to this thread (it went into a different mail folder). Lyle, have you see the Oracle::OCI module? It provides deep integration between Oracle::OCI and DBD::Oracle. To make that possible I added a get_oci_handle function pointer to DBD::Oracle's handles. It lets you ask for any kind of OCI handle from any kind of DBI handle (drh, dbh, sth). Oracle::OCI calls it like this: void * get_oci_handle(SV *h, int handle_type, int flags) { STRLEN lna; typedef void *(*hook_type)_((imp_xxh_t *imp_xxh, int handle_type, int flags)); hook_type hook; /* D_imp_xxh(h); */ imp_xxh_t *imp_xxh; if (flags 1) warn(get_oci_handle(%s,%d,%d), SvPV(h,lna), handle_type, flags); imp_xxh = (imp_xxh_t*)(DBIh_COM(h)); if (DBIc_TYPE(imp_xxh) == DBIt_ST) hook = (hook_type)((imp_sth_t*)imp_xxh)-get_oci_handle; else if (DBIc_TYPE(imp_xxh) == DBIt_DB) hook = (hook_type)((imp_dbh_t*)imp_xxh)-get_oci_handle; else croak(Can't get oci handle type %d from %s. Unsupported DBI handle type, handle_type, SvPV(h,lna)); return hook(imp_xxh, handle_type, flags); } Then calls it like this: get_oci_handle(arg, OCI_HTYPE_ERROR, 0); get_oci_handle(arg, OCI_HTYPE_SVCCTX, 0); get_oci_handle(arg, OCI_HTYPE_ENV, 0); get_oci_handle(arg, OCI_HTYPE_SERVER, 0); get_oci_handle(arg, OCI_HTYPE_SESSION, 0); get_oci_handle(arg, OCI_HTYPE_STMT, 0); I'd have no objection to adding a perl method to DBD::Oracle to access the get_oci_handle function. Perhaps ora_get_oci_handle($handle_type). Tim [still sad that Oracle::OCI doesn't get more love] On Thu, Oct 27, 2011 at 02:39:15PM -0400, Lyle Brooks wrote: Ok, so with the following addition to Oracle.pm DBD::Oracle::db-install_method(ora_oci_handles); my little test program worked. By worked, I mean I did a connect to the database, then did my @h = $dbh-ora_oci_handles(); and it returned 4 integers (ie. the value of the pointers), which is what I expected/wanted. I haven't yet tested that I can now pass these pointer values to the C++ libraries and have them digest it properly...but that would be next. As for how much anyone else might find use for thisprobably not a wide audience. But it is a nice hack! Thanks for the pointers. Quoting John Scoles (byter...@hotmail.com): Date: Thu, 27 Oct 2011 14:14:03 -0400 From: bro...@deseret.com To: martin.ev...@easysoft.com CC: dbi-users@perl.org Subject: Re: DBD-Oracle - obtaining OCI handles from $dbh Thanks for those pointers. I do agree with what Martin points out. My Perl script using DBI and some XS bindings to the legacy C++ libraries would share the same address space (not using threads in my application). This is why I thought I could return the handles/pointers as scalars. Taking John's suggestions, here is a quick code hack that I made to Oracle.xs (I haven't tested this ...other than it compiles). Looks like it should work. ;-) void ora_oci_handles(dbh) SV *dbh PREINIT: D_imp_dbh(dbh); PPCODE: /* Verify what is passed in is a $dbh object */ if ( ! sv_derived_from(ST(0), DBI::db)) { Perl_croak(aTHX_ dbh is not of type DBI::db); } mXPUSHi( (IV) imp_dbh-envhp ); /* Environment handle */ mXPUSHi( (IV) imp_dbh-svchp ); /* Service Context handle */ mXPUSHi( (IV) imp_dbh-srvhp ); /* Server handle */ mXPUSHi( (IV) imp_dbh-authp ); /* Session handle */ XSRETURN(4); Then my idea is to use this in Perl space... my($envhp, $svchp, $srvhp, $authp) = $dbh-ora_oci_handles(); # Now share the OCI handles from DBI with the custom # C++ libraries. my $cpp_dbh = MyCppOracleClass-new(); # creates custom C++ object $cpp_dbh-envhp($envhp); $cpp_dbh-svchp($svchp); $cpp_dbh-srvhp($srvhp); $cpp_dbh-authp($authp); # Do something interesting with the C++ object $cpp_dbh-make_legacy_call_to_db(); Yup that should work I didn't put two and two together and figure you already had XS for the C++. It could be something we could add to DBD::Oracle but I would return all of the handles not just the few you need. I wonder how much it would be used though?? Cheers Quoting Martin J. Evans (martin.ev...@easysoft.com): On 27/10/2011 17:43, John Scoles wrote: Hmm!! Well yes could be done but not as part of any release of DBD::Oracle it would have to be you own hacked version Why is that John? What is the problem with returning a C pointer via a DBD::Oracle attribute? It is just a pointer to some memory and loads of XS modules do this. There is an Oracle OCI module I played with for a short time but it is problematic to build. I looked at it as I could implement OCI calls
RE: DBD-Oracle - obtaining OCI handles from $dbh
Tim, I have looked at the Oracle::OCI module. I really like the concept, and it would undeniably be an extremely useful and powerful tool. However, I couldn't get it to work (by that I mean...I couldn't get it to build). As I understand Oracle::OCI, rather than provide a handcrafted XS? interface to all the OCI C functions, the Oracle::OCI module attempts to parse the OCI C header files and then auto-build the XS glue routines. This is a laudable approach, as there are a significant number of OCI functions to inteface with. The difficulty I ran into was that I could not get the parsing of the OCI header files to work properly. I tried the altered h2xs program that came with Oracle::OCI, but I failed in getting that to work with my Oracle installation. I also tried looking into a couple other approaches to parsing the OCI header files and autogenerating the XS routines, but again...my results were not fruitful. The only other comment I have on that approach is that the? interface comes out looking very C-like...meaning, the Perl interface looks almost like the OCI C interface, which is not too surprising. I found myself wishing that Oracle::OCI would look more Perl-ish. Of course, I understand the? argument that by mirroring the OCI C interface, then the Perl interface is consistent with the OCI C documentation and hence there would not be a need to learn two OCI interfaces. My work uses a good deal of the Oracle AQ functionality, and so I've found myself repeated wishing that I could find a? way to Oracle::OCI work...but it has left me mostly frustrated. Lyle Quoting Tim Bunce (tim.bu...@pobox.com): I'm late to this thread (it went into a different mail folder). Lyle, have you see the Oracle::OCI module? It provides deep integration between Oracle::OCI and DBD::Oracle. To make that possible I added a get_oci_handle function pointer to DBD::Oracle's handles. It lets you ask for any kind of OCI handle from any kind of DBI handle (drh, dbh, sth). Oracle::OCI calls it like this: void * get_oci_handle(SV *h, int handle_type, int flags) { STRLEN lna; typedef void *(*hook_type)_((imp_xxh_t *imp_xxh, int handle_type, int flags)); hook_type hook; /* D_imp_xxh(h); */ imp_xxh_t *imp_xxh; if (flags 1) warn(get_oci_handle(%s,%d,%d), SvPV(h,lna), handle_type, flags); imp_xxh = (imp_xxh_t*)(DBIh_COM(h)); if (DBIc_TYPE(imp_xxh) == DBIt_ST) hook = (hook_type)((imp_sth_t*)imp_xxh)-get_oci_handle; else if (DBIc_TYPE(imp_xxh) == DBIt_DB) hook = (hook_type)((imp_dbh_t*)imp_xxh)-get_oci_handle; else croak(Can't get oci handle type %d from %s. Unsupported DBI handle type, handle_type, SvPV(h,lna)); return hook(imp_xxh, handle_type, flags); } Then calls it like this: get_oci_handle(arg, OCI_HTYPE_ERROR, 0); get_oci_handle(arg, OCI_HTYPE_SVCCTX, 0); get_oci_handle(arg, OCI_HTYPE_ENV, 0); get_oci_handle(arg, OCI_HTYPE_SERVER, 0); get_oci_handle(arg, OCI_HTYPE_SESSION, 0); get_oci_handle(arg, OCI_HTYPE_STMT, 0); I'd have no objection to adding a perl method to DBD::Oracle to access the get_oci_handle function. Perhaps ora_get_oci_handle($handle_type). Tim [still sad that Oracle::OCI doesn't get more love] On Thu, Oct 27, 2011 at 02:39:15PM -0400, Lyle Brooks wrote: Ok, so with the following addition to Oracle.pm DBD::Oracle::db-install_method(ora_oci_handles); my little test program worked. By worked, I mean I did a connect to the database, then did my @h = $dbh-ora_oci_handles(); and it returned 4 integers (ie. the value of the pointers), which is what I expected/wanted. I haven't yet tested that I can now pass these pointer values to the C++ libraries and have them digest it properly...but that would be next. As for how much anyone else might find use for thisprobably not a wide audience. But it is a nice hack! Thanks for the pointers. Quoting John Scoles (byter...@hotmail.com): Date: Thu, 27 Oct 2011 14:14:03 -0400 From: bro...@deseret.com To: martin.ev...@easysoft.com CC: dbi-users@perl.org Subject: Re: DBD-Oracle - obtaining OCI handles from $dbh Thanks for those pointers. I do agree with what Martin points out. My Perl script using DBI and some XS bindings to the legacy C++ libraries would share the same address space (not using threads in my application). This is why I thought I could return the handles/pointers as scalars. Taking John's suggestions, here is a quick code hack that I made to Oracle.xs (I haven't tested this ...other than it compiles). Looks like it should work. ;-) void ora_oci_handles(dbh) SV *dbh PREINIT: D_imp_dbh(dbh); PPCODE: /* Verify what is passed in is a $dbh object
Re: DBD-Oracle - obtaining OCI handles from $dbh
On 28/10/11 16:09, Lyle Brooks wrote: Tim, I have looked at the Oracle::OCI module. I really like the concept, and it would undeniably be an extremely useful and powerful tool. However, I couldn't get it to work (by that I mean...I couldn't get it to build). I still use Oracle::OCI. There is a patch below which may allow you to build it under Oracle 11.2. As you will see, I have kept it going by botching things. Whenever a new feature of OCI causes trouble, I add it to the list of features to omit. I would like to do a better job, but I simply don't have the time. All I can do is to offer this patch on an as-seen basis, in the hope that it might inspire some else to do a proper job of rescuing Oracle::OCI. diff -ur Oracle-OCI-0.06.clean/01base.t Oracle-OCI-0.06.patched/01base.t --- Oracle-OCI-0.06.clean/01base.t 2001-08-31 23:02:45.0 +0100 +++ Oracle-OCI-0.06.patched/01base.t2011-10-17 10:52:24.204427839 +0100 @@ -96,7 +96,7 @@ ok OCIAttrSet($$authp, OCI_HTYPE_SESSION, @user_buf_len, OCI_ATTR_USERNAME, $errhp), 0; ok OCIAttrSet($$authp, OCI_HTYPE_SESSION, @pass_buf_len, OCI_ATTR_PASSWORD, $errhp), 0; -ok $status=OCISessionBegin($svchp, $errhp, $authp, OCI_CRED_RDBMS, OCI_DEFAULT), 0; +ok $status=OCISessionBegin($svchp, $errhp, $authp, $user ? OCI_CRED_RDBMS : OCI_CRED_EXT, OCI_DEFAULT), 0; warn get_oci_error($errhp, $status) unless $status == OCI_SUCCESS; ok OCIAttrSet($$svchp, OCI_HTYPE_SVCCTX, $$authp, 0, OCI_ATTR_SESSION, $errhp), 0; diff -ur Oracle-OCI-0.06.clean/boot Oracle-OCI-0.06.patched/boot --- Oracle-OCI-0.06.clean/boot 2001-08-30 16:49:24.0 +0100 +++ Oracle-OCI-0.06.patched/boot2011-10-17 11:31:37.856430344 +0100 @@ -1,9 +1,8 @@ -#!/opt/perl5/bin/perl -w - require 5.6.0; use strict; use Carp; +use Config; use File::Path; use File::Copy; use File::Basename; @@ -17,6 +16,15 @@ $| = 1; +# The following is based on conventions entirely local to Jackdaw. +# Perl install trees are at /usr/local/perl/version-letter. +# Libraries for DBD::Oracle are at $ORACLE_HOME/PERL/version-letter/lib/DBD/Oracle. + +my $perlpath = $Config{perlpath}; +my $perlvl = (split /\//, $perlpath)[-3]; +my $ora_arch_dir = $ENV{ORACLE_HOME}/PERL/$perlvl/lib/auto/DBD/Oracle; + +print Oracle arch dir is $ora_arch_dir\n; # configuration section. @@ -99,6 +107,21 @@ TypeArrayByRef = ?, EnvCallback = ?, SharedLibInit = uses 'dvoid *argv[]' type that we've not supported yet, +XmlDbInitXmlCtx = , +XmlDbFreeXmlCtx = , +XmlDbGetFullyQualifiedSchemaUrl = , +XmlDbMemCallback = , +XmlDbOrastreamFromLob = , +XmlDbRewriteXMLDiff = , +XmlDbStreamClose = , +XmlDbStreamFromXMLType = , +XmlDbStreamRead = , +XmlFreeDRCtx = , +XmlInitDRCtx = , +LobGetDeduplicateRegions = , +XStreamInLCRCallbackSend = , +XStreamOutLCRCallbackReceive = , + NumberToRealArray = , '_ORACLE' = empty define - used to prevent multiple #includes, '_FLAGS'= empty define - used to prevent multiple #includes, } } ], @@ -131,15 +154,14 @@ -d $orahome or croak Error: no such directory: $orahome; -r _ -x _ or croak Error: bad mods on $orahome; -my $demodir = $orahome/rdbms/demo; --d $demodir or croak Error: no directory '$demodir'; --r _ -x _ or croak Error: bad mods on '$demodir'; -my $oci_hdr = $demodir/oci.h; +my $publicdir = $orahome/rdbms/public; +-d $publicdir or croak Error: no directory '$publicdir'; +-r _ -x _ or croak Error: bad mods on '$publicdir'; +my $oci_hdr = $publicdir/oci.h; -e $oci_hdr or croak Error: hit by a missing oci.h; -r _or croak Error: unreadable $oci_hdr; -my @ora_dirs = ($demodir, - $orahome/rdbms/public, +my @ora_dirs = ($publicdir, $orahome/network/public, $orahome/plsql/public, ); @@ -165,7 +187,8 @@ my $skip_regex = '^OCI(?!' . join('|',@skip_list) . ')|^SQL'; my @h2xsargz = ( -qw( ./h2xs -d -O -n Oracle::OCI ), +$perlpath, +qw( h2xs -d -O -n Oracle::OCI ), -F .join( , map { -I$_ } @ora_dirs), -I.join(,, @ora_dirs), -E get_oci_error,get_oci_handle,oci_buf_len,OCIAttrGet, @@ -293,8 +316,7 @@ use DBI::DBD; my $dbi_dir = dbd_dbi_dir(); my $dbi_arch_dir = dbd_dbi_arch_dir(); - (my $ora_arch_dir = $dbi_arch_dir) =~ s!DBI$!DBD/Oracle!; - }.\n if $. == 1; + my $ora_arch_dir = }.'$ora_arch_dir';\n\n if $. == 1; s!^\);! CONFIGURE = \\wmf_config,\n);!; print $new_mk $_; } @@ -323,7 +345,7 @@ } print Building...\n; -system(perl Makefile.PL make make test); +system($perlpath Makefile.PL make make test) exit 1; exit 0; diff -ur Oracle-OCI-0.06.clean/extra.typemap Oracle-OCI-0.06.patched/extra.typemap ---
Re: DBD-Oracle - obtaining OCI handles from $dbh
): Date: Thu, 27 Oct 2011 14:14:03 -0400 From: bro...@deseret.com To: martin.ev...@easysoft.com CC: dbi-users@perl.org Subject: Re: DBD-Oracle - obtaining OCI handles from $dbh Thanks for those pointers. I do agree with what Martin points out. My Perl script using DBI and some XS bindings to the legacy C++ libraries would share the same address space (not using threads in my application). This is why I thought I could return the handles/pointers as scalars. Taking John's suggestions, here is a quick code hack that I made to Oracle.xs (I haven't tested this ...other than it compiles). Looks like it should work. ;-) void ora_oci_handles(dbh) SV *dbh PREINIT: D_imp_dbh(dbh); PPCODE: /* Verify what is passed in is a $dbh object */ if ( ! sv_derived_from(ST(0), DBI::db)) { Perl_croak(aTHX_ dbh is not of type DBI::db); } mXPUSHi( (IV) imp_dbh-envhp ); /* Environment handle */ mXPUSHi( (IV) imp_dbh-svchp ); /* Service Context handle */ mXPUSHi( (IV) imp_dbh-srvhp ); /* Server handle */ mXPUSHi( (IV) imp_dbh-authp ); /* Session handle */ XSRETURN(4); Then my idea is to use this in Perl space... my($envhp, $svchp, $srvhp, $authp) = $dbh-ora_oci_handles(); # Now share the OCI handles from DBI with the custom # C++ libraries. my $cpp_dbh = MyCppOracleClass-new(); # creates custom C++ object $cpp_dbh-envhp($envhp); $cpp_dbh-svchp($svchp); $cpp_dbh-srvhp($srvhp); $cpp_dbh-authp($authp); # Do something interesting with the C++ object $cpp_dbh-make_legacy_call_to_db(); Yup that should work I didn't put two and two together and figure you already had XS for the C++. It could be something we could add to DBD::Oracle but I would return all of the handles not just the few you need. I wonder how much it would be used though?? Cheers Quoting Martin J. Evans (martin.ev...@easysoft.com): On 27/10/2011 17:43, John Scoles wrote: Hmm!! Well yes could be done but not as part of any release of DBD::Oracle it would have to be you own hacked version Why is that John? What is the problem with returning a C pointer via a DBD::Oracle attribute? It is just a pointer to some memory and loads of XS modules do this. There is an Oracle OCI module I played with for a short time but it is problematic to build. I looked at it as I could implement OCI calls separately from DBD::Oracle. I don't seem the harm in exposing OCI handles via DBD::Oracle - it would be useful for people like the OP. A few pointers to start. You will not be able to 'get' a handle and retrun it as a Scalar it will only ever be a pointer so you will just get some sort of number, You would simly edit the Oracle.xs file add in the includes to your C++ .h files then add a few extra 'ora_' functions to take care of you C++ calls; A quick example void ora_some_c_call(dbh) SV *dbh PREINIT: D_imp_dbh(dbh); //this gets all the OCI handles for you (see dbdimp.h for the sturct imp_dbh_st) CODE: MYSomeC_Plus_Plus_method(dbh-envhp,dbh-svchp,dbh-seshp,dbh-srvhp); He does not need to do this surely. So long as the C++ code and DBD::Oracle XS is running in the same process the pointers obtained from DBD::Oracle are just as valid in the C++ code as XS. However, if the code is multi-threaded there could be issues of multiple threads accessing the OCI handles at the same time. Myself I would write a small 'c' wrapper that would call you c++ and just a single .XS function that calls that small 'c' wrapper to fire your function. My impression was that this was already done. I quote: I have created some Perl bindings for some existing custom C++ libraries. Martin -- Martin J. Evans Easysoft Limited http://www.easysoft.com Hope this helps Cheers John Date: Thu, 27 Oct 2011 09:48:54 -0400 From: bro...@deseret.com To: byter...@hotmail.com CC: dbi-users@perl.org Subject: Re: DBI-Users RE: DBD-Oracle - obtaining OCI handles from $dbh Yes, I assumed I would need to extend DBD::Oracle is some manner to allow those handles to be extracted from a $dbh object. The specific OCI handles that the C++ libraries use are - Environment handle - Service Context handle - Session handle - Server handle My initial thought process on how it might work is this Create a method in the DBD::Oracle XS code to retrieve those handles and return them back to Perl space as a scalar. Then with the Perl scalars that hold the OCI handles obtained from $dbh, pass those values to my Perl bindings to the custom C++ libraries. (I would need to extend the C++ libraries to allow the set methods to the objects that hold those OCI handles). ...then the C++ libraries should work the same. The motivation for this approach is that I have a large code base of these C++ libraries that have been tested, so it would cost prohibitive to simply replace them with a pure Perl implementation. However, it is so much easier to work with Perl and DBI, it would be useful to have DBI connect to the database and do some table lookups. The C++ code could then be integrated
Re: DBD-Oracle - obtaining OCI handles from $dbh
On 28/10/2011 16:34, Charles Jardine wrote: On 28/10/11 16:09, Lyle Brooks wrote: Tim, I have looked at the Oracle::OCI module. I really like the concept, and it would undeniably be an extremely useful and powerful tool. However, I couldn't get it to work (by that I mean...I couldn't get it to build). I still use Oracle::OCI. There is a patch below which may allow you to build it under Oracle 11.2. As you will see, I have kept it going by botching things. Whenever a new feature of OCI causes trouble, I add it to the list of features to omit. I would like to do a better job, but I simply don't have the time. All I can do is to offer this patch on an as-seen basis, in the hope that it might inspire some else to do a proper job of rescuing Oracle::OCI. Aha, I thought it was you Charles who helped me last time I tried to build Oracle::OCI. Perhaps I'll find time to give it another go. Martin -- Martin J. Evans Easysoft Limited http://www.easysoft.com
Re: DBD-Oracle - obtaining OCI handles from $dbh
On Fri, Oct 28, 2011 at 05:19:33PM +0100, Martin J. Evans wrote: On 28/10/2011 16:34, Charles Jardine wrote: I still use Oracle::OCI. There is a patch below which may allow you to build it under Oracle 11.2. As you will see, I have kept it going by botching things. Whenever a new feature of OCI causes trouble, I add it to the list of features to omit. I would like to do a better job, but I simply don't have the time. All I can do is to offer this patch on an as-seen basis, in the hope that it might inspire some else to do a proper job of rescuing Oracle::OCI. Aha, I thought it was you Charles who helped me last time I tried to build Oracle::OCI. Perhaps I'll find time to give it another go. That would be awesome. Tim.
Re: DBD-Oracle - obtaining OCI handles from $dbh
On Fri, Oct 28, 2011 at 11:09:20AM -0400, Lyle Brooks wrote: The only other comment I have on that approach is that the� interface comes out looking very C-like...meaning, the Perl interface looks almost like the OCI C interface, which is not too surprising. I found myself wishing that Oracle::OCI would look more Perl-ish. Of course, I understand the� argument that by mirroring the OCI C interface, then the Perl interface is consistent with the OCI C documentation and hence there would not be a need to learn two OCI interfaces. I'd hope people would develop higher-level interfaces for various aspects of Oracle functionality using Oracle::OCI as an underlying API. An Oracle::AQ module for example. My work uses a good deal of the Oracle AQ functionality, and so I've found myself repeated wishing that I could find a� way to Oracle::OCI work...but it has left me mostly frustrated. Hopefully between Charles, Martin, and yourself, we can breath some new life into Oracle::OCI. Tim.
Re: DBD-Oracle - obtaining OCI handles from $dbh
On 27/10/2011 02:46, Lyle Brooks wrote: I have created some Perl bindings for some existing custom C++ libraries. One of these C++ libraries implements a class that uses Oracle OCI calls. I would like to create a connection to the Oracle database using Perl's DBI (DBD::Oracle) module, and then ideally share that connection with the C++ libraries. This would require me to extract the Oracle OCI handles from the $dbh object...and then pass them to the C++ libraries. What would be the best way to get access to the underlying Oracle OCI handles from a $dbh object? I could be wrong but I don't think there is a way right now. You'd need to add an attribute or 2 on the $dbh to return them. It is fairly easy and if you've done some XS already I doubt you'd have much problem. Just do a search for an attribute like ora_parse_error_offset. Martin -- Martin J. Evans Easysoft Limited http://www.easysoft.com
RE: DBD-Oracle - obtaining OCI handles from $dbh
Date: Wed, 26 Oct 2011 21:46:30 -0400 From: bro...@deseret.com To: dbi-users@perl.org Subject: DBD-Oracle - obtaining OCI handles from $dbh I have created some Perl bindings for some existing custom C++ libraries. One of these C++ libraries implements a class that uses Oracle OCI calls. I would like to create a connection to the Oracle database using Perl's DBI (DBD::Oracle) module, and then ideally share that connection with the C++ libraries. This would require me to extract the Oracle OCI handles from the $dbh object...and then pass them to the C++ libraries. What would be the best way to get access to the underlying Oracle OCI handles from a $dbh object? Hmm! Interesting concept. Which OCI handles are we talking about?? Like Matin said you would have to do that with .XS and you would pass I guess a pointer to the 'C' struct that holds the pointers to DBD::Oraclles pointers? You would have to cast that struct into you C++ somehow?? There would be a good number of handles to pass over. You might be able to find them by looking at the Perl process tree and finding the SV that holds the struct and then sening that over? All just guesses on my part. Interesting concept non the less. Cheers John
Re: DBI-Users RE: DBD-Oracle - obtaining OCI handles from $dbh
Yes, I assumed I would need to extend DBD::Oracle is some manner to allow those handles to be extracted from a $dbh object. The specific OCI handles that the C++ libraries use are - Environment handle - Service Context handle - Session handle - Server handle My initial thought process on how it might work is this Create a method in the DBD::Oracle XS code to retrieve those handles and return them back to Perl space as a scalar. Then with the Perl scalars that hold the OCI handles obtained from $dbh, pass those values to my Perl bindings to the custom C++ libraries. (I would need to extend the C++ libraries to allow the set methods to the objects that hold those OCI handles). ...then the C++ libraries should work the same. The motivation for this approach is that I have a large code base of these C++ libraries that have been tested, so it would cost prohibitive to simply replace them with a pure Perl implementation. However, it is so much easier to work with Perl and DBI, it would be useful to have DBI connect to the database and do some table lookups. The C++ code could then be integrated seemlessly with my Perl code. As time allows, I would gradually peel away functionality from the legacy C++ libraries and implement it in Perl. But to ease the migration path, this approach seemed to have some merits. Quoting John Scoles (byter...@hotmail.com): Date: Wed, 26 Oct 2011 21:46:30 -0400 From: bro...@deseret.com To: dbi-users@perl.org Subject: DBD-Oracle - obtaining OCI handles from $dbh I have created some Perl bindings for some existing custom C++ libraries. One of these C++ libraries implements a class that uses Oracle OCI calls. I would like to create a connection to the Oracle database using Perl's DBI (DBD::Oracle) module, and then ideally share that connection with the C++ libraries. This would require me to extract the Oracle OCI handles from the $dbh object...and then pass them to the C++ libraries. What would be the best way to get access to the underlying Oracle OCI handles from a $dbh object? Hmm! Interesting concept. Which OCI handles are we talking about?? Like Matin said you would have to do that with .XS and you would pass I guess a pointer to the 'C' struct that holds the pointers to DBD::Oraclles pointers? You would have to cast that struct into you C++ somehow?? There would be a good number of handles to pass over. You might be able to find them by looking at the Perl process tree and finding the SV that holds the struct and then sening that over? All just guesses on my part. Interesting concept non the less. Cheers John
RE: DBI-Users RE: DBD-Oracle - obtaining OCI handles from $dbh
Hmm!! Well yes could be done but not as part of any release of DBD::Oracle it would have to be you own hacked version A few pointers to start. You will not be able to 'get' a handle and retrun it as a Scalar it will only ever be a pointer so you will just get some sort of number, You would simly edit the Oracle.xs file add in the includes to your C++ .h files then add a few extra 'ora_' functions to take care of you C++ calls; A quick example void ora_some_c_call(dbh) SV *dbh PREINIT: D_imp_dbh(dbh); //this gets all the OCI handles for you (see dbdimp.h for the sturct imp_dbh_st) CODE: MYSomeC_Plus_Plus_method(dbh-envhp,dbh-svchp,dbh-seshp,dbh-srvhp); Myself I would write a small 'c' wrapper that would call you c++ and just a single .XS function that calls that small 'c' wrapper to fire your function. Hope this helps Cheers John Date: Thu, 27 Oct 2011 09:48:54 -0400 From: bro...@deseret.com To: byter...@hotmail.com CC: dbi-users@perl.org Subject: Re: DBI-Users RE: DBD-Oracle - obtaining OCI handles from $dbh Yes, I assumed I would need to extend DBD::Oracle is some manner to allow those handles to be extracted from a $dbh object. The specific OCI handles that the C++ libraries use are - Environment handle - Service Context handle - Session handle - Server handle My initial thought process on how it might work is this Create a method in the DBD::Oracle XS code to retrieve those handles and return them back to Perl space as a scalar. Then with the Perl scalars that hold the OCI handles obtained from $dbh, pass those values to my Perl bindings to the custom C++ libraries. (I would need to extend the C++ libraries to allow the set methods to the objects that hold those OCI handles). ...then the C++ libraries should work the same. The motivation for this approach is that I have a large code base of these C++ libraries that have been tested, so it would cost prohibitive to simply replace them with a pure Perl implementation. However, it is so much easier to work with Perl and DBI, it would be useful to have DBI connect to the database and do some table lookups. The C++ code could then be integrated seemlessly with my Perl code. As time allows, I would gradually peel away functionality from the legacy C++ libraries and implement it in Perl. But to ease the migration path, this approach seemed to have some merits. Quoting John Scoles (byter...@hotmail.com): Date: Wed, 26 Oct 2011 21:46:30 -0400 From: bro...@deseret.com To: dbi-users@perl.org Subject: DBD-Oracle - obtaining OCI handles from $dbh I have created some Perl bindings for some existing custom C++ libraries. One of these C++ libraries implements a class that uses Oracle OCI calls. I would like to create a connection to the Oracle database using Perl's DBI (DBD::Oracle) module, and then ideally share that connection with the C++ libraries. This would require me to extract the Oracle OCI handles from the $dbh object...and then pass them to the C++ libraries. What would be the best way to get access to the underlying Oracle OCI handles from a $dbh object? Hmm! Interesting concept. Which OCI handles are we talking about?? Like Matin said you would have to do that with .XS and you would pass I guess a pointer to the 'C' struct that holds the pointers to DBD::Oraclles pointers? You would have to cast that struct into you C++ somehow?? There would be a good number of handles to pass over. You might be able to find them by looking at the Perl process tree and finding the SV that holds the struct and then sening that over? All just guesses on my part. Interesting concept non the less. Cheers John
Re: DBI-Users RE: DBD-Oracle - obtaining OCI handles from $dbh
On 27/10/2011 17:43, John Scoles wrote: Hmm!! Well yes could be done but not as part of any release of DBD::Oracle it would have to be you own hacked version Why is that John? What is the problem with returning a C pointer via a DBD::Oracle attribute? It is just a pointer to some memory and loads of XS modules do this. There is an Oracle OCI module I played with for a short time but it is problematic to build. I looked at it as I could implement OCI calls separately from DBD::Oracle. I don't seem the harm in exposing OCI handles via DBD::Oracle - it would be useful for people like the OP. A few pointers to start. You will not be able to 'get' a handle and retrun it as a Scalar it will only ever be a pointer so you will just get some sort of number, You would simly edit the Oracle.xs file add in the includes to your C++ .h files then add a few extra 'ora_' functions to take care of you C++ calls; A quick example void ora_some_c_call(dbh) SV *dbh PREINIT: D_imp_dbh(dbh); //this gets all the OCI handles for you (see dbdimp.h for the sturct imp_dbh_st) CODE: MYSomeC_Plus_Plus_method(dbh-envhp,dbh-svchp,dbh-seshp,dbh-srvhp); He does not need to do this surely. So long as the C++ code and DBD::Oracle XS is running in the same process the pointers obtained from DBD::Oracle are just as valid in the C++ code as XS. However, if the code is multi-threaded there could be issues of multiple threads accessing the OCI handles at the same time. Myself I would write a small 'c' wrapper that would call you c++ and just a single .XS function that calls that small 'c' wrapper to fire your function. My impression was that this was already done. I quote: I have created some Perl bindings for some existing custom C++ libraries. Martin -- Martin J. Evans Easysoft Limited http://www.easysoft.com Hope this helps Cheers John Date: Thu, 27 Oct 2011 09:48:54 -0400 From: bro...@deseret.com To: byter...@hotmail.com CC: dbi-users@perl.org Subject: Re: DBI-Users RE: DBD-Oracle - obtaining OCI handles from $dbh Yes, I assumed I would need to extend DBD::Oracle is some manner to allow those handles to be extracted from a $dbh object. The specific OCI handles that the C++ libraries use are - Environment handle - Service Context handle - Session handle - Server handle My initial thought process on how it might work is this Create a method in the DBD::Oracle XS code to retrieve those handles and return them back to Perl space as a scalar. Then with the Perl scalars that hold the OCI handles obtained from $dbh, pass those values to my Perl bindings to the custom C++ libraries. (I would need to extend the C++ libraries to allow the set methods to the objects that hold those OCI handles). ...then the C++ libraries should work the same. The motivation for this approach is that I have a large code base of these C++ libraries that have been tested, so it would cost prohibitive to simply replace them with a pure Perl implementation. However, it is so much easier to work with Perl and DBI, it would be useful to have DBI connect to the database and do some table lookups. The C++ code could then be integrated seemlessly with my Perl code. As time allows, I would gradually peel away functionality from the legacy C++ libraries and implement it in Perl. But to ease the migration path, this approach seemed to have some merits. Quoting John Scoles (byter...@hotmail.com): Date: Wed, 26 Oct 2011 21:46:30 -0400 From: bro...@deseret.com To: dbi-users@perl.org Subject: DBD-Oracle - obtaining OCI handles from $dbh I have created some Perl bindings for some existing custom C++ libraries. One of these C++ libraries implements a class that uses Oracle OCI calls. I would like to create a connection to the Oracle database using Perl's DBI (DBD::Oracle) module, and then ideally share that connection with the C++ libraries. This would require me to extract the Oracle OCI handles from the $dbh object...and then pass them to the C++ libraries. What would be the best way to get access to the underlying Oracle OCI handles from a $dbh object? Hmm! Interesting concept. Which OCI handles are we talking about?? Like Matin said you would have to do that with .XS and you would pass I guess a pointer to the 'C' struct that holds the pointers to DBD::Oraclles pointers? You would have to cast that struct into you C++ somehow?? There would be a good number of handles to pass over. You might be able to find them by looking at the Perl process tree and finding the SV that holds the struct and then sening that over? All just guesses on my part. Interesting concept non the less. Cheers John
Re: DBD-Oracle - obtaining OCI handles from $dbh
Thanks for those pointers. I do agree with what Martin points out. My Perl script using DBI and some XS bindings to the legacy C++ libraries would share the same address space (not using threads in my application). This is why I thought I could return the handles/pointers as scalars. Taking John's suggestions, here is a quick code hack that I made to Oracle.xs (I haven't tested this ...other than it compiles). Looks like it should work. ;-) void ora_oci_handles(dbh) SV *dbh PREINIT: D_imp_dbh(dbh); PPCODE: /* Verify what is passed in is a $dbh object */ if ( ! sv_derived_from(ST(0), DBI::db)) { Perl_croak(aTHX_ dbh is not of type DBI::db); } mXPUSHi( (IV) imp_dbh-envhp );/* Environment handle */ mXPUSHi( (IV) imp_dbh-svchp );/* Service Context handle */ mXPUSHi( (IV) imp_dbh-srvhp );/* Server handle */ mXPUSHi( (IV) imp_dbh-authp );/* Session handle */ XSRETURN(4); Then my idea is to use this in Perl space... my($envhp, $svchp, $srvhp, $authp) = $dbh-ora_oci_handles(); # Now share the OCI handles from DBI with the custom # C++ libraries. my $cpp_dbh = MyCppOracleClass-new(); # creates custom C++ object $cpp_dbh-envhp($envhp); $cpp_dbh-svchp($svchp); $cpp_dbh-srvhp($srvhp); $cpp_dbh-authp($authp); # Do something interesting with the C++ object $cpp_dbh-make_legacy_call_to_db(); Quoting Martin J. Evans (martin.ev...@easysoft.com): On 27/10/2011 17:43, John Scoles wrote: Hmm!! Well yes could be done but not as part of any release of DBD::Oracle it would have to be you own hacked version Why is that John? What is the problem with returning a C pointer via a DBD::Oracle attribute? It is just a pointer to some memory and loads of XS modules do this. There is an Oracle OCI module I played with for a short time but it is problematic to build. I looked at it as I could implement OCI calls separately from DBD::Oracle. I don't seem the harm in exposing OCI handles via DBD::Oracle - it would be useful for people like the OP. A few pointers to start. You will not be able to 'get' a handle and retrun it as a Scalar it will only ever be a pointer so you will just get some sort of number, You would simly edit the Oracle.xs file add in the includes to your C++ .h files then add a few extra 'ora_' functions to take care of you C++ calls; A quick example void ora_some_c_call(dbh) SV *dbh PREINIT: D_imp_dbh(dbh); //this gets all the OCI handles for you (see dbdimp.h for the sturct imp_dbh_st) CODE: MYSomeC_Plus_Plus_method(dbh-envhp,dbh-svchp,dbh-seshp,dbh-srvhp); He does not need to do this surely. So long as the C++ code and DBD::Oracle XS is running in the same process the pointers obtained from DBD::Oracle are just as valid in the C++ code as XS. However, if the code is multi-threaded there could be issues of multiple threads accessing the OCI handles at the same time. Myself I would write a small 'c' wrapper that would call you c++ and just a single .XS function that calls that small 'c' wrapper to fire your function. My impression was that this was already done. I quote: I have created some Perl bindings for some existing custom C++ libraries. Martin -- Martin J. Evans Easysoft Limited http://www.easysoft.com Hope this helps Cheers John Date: Thu, 27 Oct 2011 09:48:54 -0400 From: bro...@deseret.com To: byter...@hotmail.com CC: dbi-users@perl.org Subject: Re: DBI-Users RE: DBD-Oracle - obtaining OCI handles from $dbh Yes, I assumed I would need to extend DBD::Oracle is some manner to allow those handles to be extracted from a $dbh object. The specific OCI handles that the C++ libraries use are - Environment handle - Service Context handle - Session handle - Server handle My initial thought process on how it might work is this Create a method in the DBD::Oracle XS code to retrieve those handles and return them back to Perl space as a scalar. Then with the Perl scalars that hold the OCI handles obtained from $dbh, pass those values to my Perl bindings to the custom C++ libraries. (I would need to extend the C++ libraries to allow the set methods to the objects that hold those OCI handles). ...then the C++ libraries should work the same. The motivation for this approach is that I have a large code base of these C++ libraries that have been tested, so it would cost prohibitive to simply replace them with a pure Perl implementation. However, it is so much easier to work with Perl and DBI, it would be useful to have DBI connect to the database and do some table lookups. The C++ code could then be integrated seemlessly with my Perl code. As time allows, I would gradually peel away functionality from the legacy C++ libraries and implement it in Perl. But to ease the migration path, this approach seemed to have some merits. Quoting John
RE: DBI-Users RE: DBD-Oracle - obtaining OCI handles from $dbh
Date: Thu, 27 Oct 2011 18:42:23 +0100 From: martin.ev...@easysoft.com To: dbi-users@perl.org Subject: Re: DBI-Users RE: DBD-Oracle - obtaining OCI handles from $dbh On 27/10/2011 17:43, John Scoles wrote: Hmm!! Well yes could be done but not as part of any release of DBD::Oracle it would have to be you own hacked version Why is that John? What is the problem with returning a C pointer via a DBD::Oracle attribute? It is just a pointer to some memory and loads of XS modules do this. I have no real problem with this either i guess here I am talking about calling his functions from XS as I denonstrated below. There is an Oracle OCI module I played with for a short time but it is problematic to build. I looked at it as I could implement OCI calls separately from DBD::Oracle. I don't seem the harm in exposing OCI handles via DBD::Oracle - it would be useful for people like the OP. Oh yeah the old code of Tim B. Never could get it to compile for me. I think the make file is only a few lines long and is only for 9i A few pointers to start. You will not be able to 'get' a handle and retrun it as a Scalar it will only ever be a pointer so you will just get some sort of number, You would simly edit the Oracle.xs file add in the includes to your C++ .h files then add a few extra 'ora_' functions to take care of you C++ calls; A quick example void ora_some_c_call(dbh) SV *dbh PREINIT: D_imp_dbh(dbh); //this gets all the OCI handles for you (see dbdimp.h for the sturct imp_dbh_st) CODE: MYSomeC_Plus_Plus_method(dbh-envhp,dbh-svchp,dbh-seshp,dbh-srvhp); He does not need to do this surely. So long as the C++ code and DBD::Oracle XS is running in the same process the pointers obtained from DBD::Oracle are just as valid in the C++ code as XS. However, if the code is multi-threaded there could be issues of multiple threads accessing the OCI handles at the same time. Myself I would write a small 'c' wrapper that would call you c++ and just a single .XS function that calls that small 'c' wrapper to fire your function. My impression was that this was already done. I quote: I have created some Perl bindings for some existing custom C++ libraries. I guess I am just reading it differntly than you. Anway best would be to see some prototye code so we can get an better Idea of what he wants done. If you just need the pointers to the OCI handles I think there is a way to have a look at them in Perl. Seems I remember doing that or seeing it done one day but that would be a real hack. I will have to look at some code at home. It may involve getting a little to deep into the exe tree. cheers John Martin -- Martin J. Evans Easysoft Limited http://www.easysoft.com Hope this helps Cheers John Date: Thu, 27 Oct 2011 09:48:54 -0400 From: bro...@deseret.com To: byter...@hotmail.com CC: dbi-users@perl.org Subject: Re: DBI-Users RE: DBD-Oracle - obtaining OCI handles from $dbh Yes, I assumed I would need to extend DBD::Oracle is some manner to allow those handles to be extracted from a $dbh object. The specific OCI handles that the C++ libraries use are - Environment handle - Service Context handle - Session handle - Server handle My initial thought process on how it might work is this Create a method in the DBD::Oracle XS code to retrieve those handles and return them back to Perl space as a scalar. Then with the Perl scalars that hold the OCI handles obtained from $dbh, pass those values to my Perl bindings to the custom C++ libraries. (I would need to extend the C++ libraries to allow the set methods to the objects that hold those OCI handles). ...then the C++ libraries should work the same. The motivation for this approach is that I have a large code base of these C++ libraries that have been tested, so it would cost prohibitive to simply replace them with a pure Perl implementation. However, it is so much easier to work with Perl and DBI, it would be useful to have DBI connect to the database and do some table lookups. The C++ code could then be integrated seemlessly with my Perl code. As time allows, I would gradually peel away functionality from the legacy C++ libraries and implement it in Perl. But to ease the migration path, this approach seemed to have some merits. Quoting John Scoles (byter...@hotmail.com): Date: Wed, 26 Oct 2011 21:46:30 -0400 From: bro...@deseret.com To: dbi-users@perl.org Subject: DBD-Oracle - obtaining OCI handles from $dbh I have created some Perl bindings for some existing custom C++ libraries. One of these C++ libraries implements a class that uses Oracle OCI calls. I would like to create a connection to the Oracle database using Perl's DBI (DBD::Oracle) module, and then ideally share that connection with the C++ libraries
RE: DBD-Oracle - obtaining OCI handles from $dbh
Date: Thu, 27 Oct 2011 14:14:03 -0400 From: bro...@deseret.com To: martin.ev...@easysoft.com CC: dbi-users@perl.org Subject: Re: DBD-Oracle - obtaining OCI handles from $dbh Thanks for those pointers. I do agree with what Martin points out. My Perl script using DBI and some XS bindings to the legacy C++ libraries would share the same address space (not using threads in my application). This is why I thought I could return the handles/pointers as scalars. Taking John's suggestions, here is a quick code hack that I made to Oracle.xs (I haven't tested this ...other than it compiles). Looks like it should work. ;-) void ora_oci_handles(dbh) SV *dbh PREINIT: D_imp_dbh(dbh); PPCODE: /* Verify what is passed in is a $dbh object */ if ( ! sv_derived_from(ST(0), DBI::db)) { Perl_croak(aTHX_ dbh is not of type DBI::db); } mXPUSHi( (IV) imp_dbh-envhp ); /* Environment handle */ mXPUSHi( (IV) imp_dbh-svchp ); /* Service Context handle */ mXPUSHi( (IV) imp_dbh-srvhp ); /* Server handle */ mXPUSHi( (IV) imp_dbh-authp ); /* Session handle */ XSRETURN(4); Then my idea is to use this in Perl space... my($envhp, $svchp, $srvhp, $authp) = $dbh-ora_oci_handles(); # Now share the OCI handles from DBI with the custom # C++ libraries. my $cpp_dbh = MyCppOracleClass-new(); # creates custom C++ object $cpp_dbh-envhp($envhp); $cpp_dbh-svchp($svchp); $cpp_dbh-srvhp($srvhp); $cpp_dbh-authp($authp); # Do something interesting with the C++ object $cpp_dbh-make_legacy_call_to_db(); Yup that should work I didn't put two and two together and figure you already had XS for the C++. It could be something we could add to DBD::Oracle but I would return all of the handles not just the few you need. I wonder how much it would be used though?? Cheers Quoting Martin J. Evans (martin.ev...@easysoft.com): On 27/10/2011 17:43, John Scoles wrote: Hmm!! Well yes could be done but not as part of any release of DBD::Oracle it would have to be you own hacked version Why is that John? What is the problem with returning a C pointer via a DBD::Oracle attribute? It is just a pointer to some memory and loads of XS modules do this. There is an Oracle OCI module I played with for a short time but it is problematic to build. I looked at it as I could implement OCI calls separately from DBD::Oracle. I don't seem the harm in exposing OCI handles via DBD::Oracle - it would be useful for people like the OP. A few pointers to start. You will not be able to 'get' a handle and retrun it as a Scalar it will only ever be a pointer so you will just get some sort of number, You would simly edit the Oracle.xs file add in the includes to your C++ .h files then add a few extra 'ora_' functions to take care of you C++ calls; A quick example void ora_some_c_call(dbh) SV *dbh PREINIT: D_imp_dbh(dbh); //this gets all the OCI handles for you (see dbdimp.h for the sturct imp_dbh_st) CODE: MYSomeC_Plus_Plus_method(dbh-envhp,dbh-svchp,dbh-seshp,dbh-srvhp); He does not need to do this surely. So long as the C++ code and DBD::Oracle XS is running in the same process the pointers obtained from DBD::Oracle are just as valid in the C++ code as XS. However, if the code is multi-threaded there could be issues of multiple threads accessing the OCI handles at the same time. Myself I would write a small 'c' wrapper that would call you c++ and just a single .XS function that calls that small 'c' wrapper to fire your function. My impression was that this was already done. I quote: I have created some Perl bindings for some existing custom C++ libraries. Martin -- Martin J. Evans Easysoft Limited http://www.easysoft.com Hope this helps Cheers John Date: Thu, 27 Oct 2011 09:48:54 -0400 From: bro...@deseret.com To: byter...@hotmail.com CC: dbi-users@perl.org Subject: Re: DBI-Users RE: DBD-Oracle - obtaining OCI handles from $dbh Yes, I assumed I would need to extend DBD::Oracle is some manner to allow those handles to be extracted from a $dbh object. The specific OCI handles that the C++ libraries use are - Environment handle - Service Context handle - Session handle - Server handle My initial thought process on how it might work is this Create a method in the DBD::Oracle XS code to retrieve those handles and return them back to Perl space as a scalar. Then with the Perl scalars that hold the OCI handles obtained from $dbh, pass those values to my Perl bindings to the custom C++ libraries. (I would need to extend the C++ libraries to allow the set methods to the objects that hold those OCI handles). ...then the C++ libraries should work the same. The motivation for this approach is that I have a large code base of these C++ libraries
Re: DBI-Users RE: DBD-Oracle - obtaining OCI handles from $dbh
Ok, so with the following addition to Oracle.pm DBD::Oracle::db-install_method(ora_oci_handles); my little test program worked. By worked, I mean I did a connect to the database, then did my @h = $dbh-ora_oci_handles(); and it returned 4 integers (ie. the value of the pointers), which is what I expected/wanted. I haven't yet tested that I can now pass these pointer values to the C++ libraries and have them digest it properly...but that would be next. As for how much anyone else might find use for thisprobably not a wide audience. But it is a nice hack! Thanks for the pointers. Quoting John Scoles (byter...@hotmail.com): Date: Thu, 27 Oct 2011 14:14:03 -0400 From: bro...@deseret.com To: martin.ev...@easysoft.com CC: dbi-users@perl.org Subject: Re: DBD-Oracle - obtaining OCI handles from $dbh Thanks for those pointers. I do agree with what Martin points out. My Perl script using DBI and some XS bindings to the legacy C++ libraries would share the same address space (not using threads in my application). This is why I thought I could return the handles/pointers as scalars. Taking John's suggestions, here is a quick code hack that I made to Oracle.xs (I haven't tested this ...other than it compiles). Looks like it should work. ;-) void ora_oci_handles(dbh) SV *dbh PREINIT: D_imp_dbh(dbh); PPCODE: /* Verify what is passed in is a $dbh object */ if ( ! sv_derived_from(ST(0), DBI::db)) { Perl_croak(aTHX_ dbh is not of type DBI::db); } mXPUSHi( (IV) imp_dbh-envhp ); /* Environment handle */ mXPUSHi( (IV) imp_dbh-svchp ); /* Service Context handle */ mXPUSHi( (IV) imp_dbh-srvhp ); /* Server handle */ mXPUSHi( (IV) imp_dbh-authp ); /* Session handle */ XSRETURN(4); Then my idea is to use this in Perl space... my($envhp, $svchp, $srvhp, $authp) = $dbh-ora_oci_handles(); # Now share the OCI handles from DBI with the custom # C++ libraries. my $cpp_dbh = MyCppOracleClass-new(); # creates custom C++ object $cpp_dbh-envhp($envhp); $cpp_dbh-svchp($svchp); $cpp_dbh-srvhp($srvhp); $cpp_dbh-authp($authp); # Do something interesting with the C++ object $cpp_dbh-make_legacy_call_to_db(); Yup that should work I didn't put two and two together and figure you already had XS for the C++. It could be something we could add to DBD::Oracle but I would return all of the handles not just the few you need. I wonder how much it would be used though?? Cheers Quoting Martin J. Evans (martin.ev...@easysoft.com): On 27/10/2011 17:43, John Scoles wrote: Hmm!! Well yes could be done but not as part of any release of DBD::Oracle it would have to be you own hacked version Why is that John? What is the problem with returning a C pointer via a DBD::Oracle attribute? It is just a pointer to some memory and loads of XS modules do this. There is an Oracle OCI module I played with for a short time but it is problematic to build. I looked at it as I could implement OCI calls separately from DBD::Oracle. I don't seem the harm in exposing OCI handles via DBD::Oracle - it would be useful for people like the OP. A few pointers to start. You will not be able to 'get' a handle and retrun it as a Scalar it will only ever be a pointer so you will just get some sort of number, You would simly edit the Oracle.xs file add in the includes to your C++ .h files then add a few extra 'ora_' functions to take care of you C++ calls; A quick example void ora_some_c_call(dbh) SV *dbh PREINIT: D_imp_dbh(dbh); //this gets all the OCI handles for you (see dbdimp.h for the sturct imp_dbh_st) CODE: MYSomeC_Plus_Plus_method(dbh-envhp,dbh-svchp,dbh-seshp,dbh-srvhp); He does not need to do this surely. So long as the C++ code and DBD::Oracle XS is running in the same process the pointers obtained from DBD::Oracle are just as valid in the C++ code as XS. However, if the code is multi-threaded there could be issues of multiple threads accessing the OCI handles at the same time. Myself I would write a small 'c' wrapper that would call you c++ and just a single .XS function that calls that small 'c' wrapper to fire your function. My impression was that this was already done. I quote: I have created some Perl bindings for some existing custom C++ libraries. Martin -- Martin J. Evans Easysoft Limited http://www.easysoft.com Hope this helps Cheers John Date: Thu, 27 Oct 2011 09:48:54 -0400 From: bro...@deseret.com To: byter...@hotmail.com CC: dbi-users@perl.org Subject: Re: DBI-Users RE: DBD-Oracle - obtaining OCI handles from $dbh Yes, I assumed I would need to extend DBD::Oracle is some manner to allow
RE: DBI-Users RE: DBD-Oracle - obtaining OCI handles from $dbh
Glad we can help. Keep us informed on how it works out cheers John Date: Thu, 27 Oct 2011 14:39:15 -0400 From: bro...@deseret.com To: byter...@hotmail.com CC: martin.ev...@easysoft.com; dbi-users@perl.org Subject: Re: DBI-Users RE: DBD-Oracle - obtaining OCI handles from $dbh Ok, so with the following addition to Oracle.pm DBD::Oracle::db-install_method(ora_oci_handles); my little test program worked. By worked, I mean I did a connect to the database, then did my @h = $dbh-ora_oci_handles(); and it returned 4 integers (ie. the value of the pointers), which is what I expected/wanted. I haven't yet tested that I can now pass these pointer values to the C++ libraries and have them digest it properly...but that would be next. As for how much anyone else might find use for thisprobably not a wide audience. But it is a nice hack! Thanks for the pointers. Quoting John Scoles (byter...@hotmail.com): Date: Thu, 27 Oct 2011 14:14:03 -0400 From: bro...@deseret.com To: martin.ev...@easysoft.com CC: dbi-users@perl.org Subject: Re: DBD-Oracle - obtaining OCI handles from $dbh Thanks for those pointers. I do agree with what Martin points out. My Perl script using DBI and some XS bindings to the legacy C++ libraries would share the same address space (not using threads in my application). This is why I thought I could return the handles/pointers as scalars. Taking John's suggestions, here is a quick code hack that I made to Oracle.xs (I haven't tested this ...other than it compiles). Looks like it should work. ;-) void ora_oci_handles(dbh) SV *dbh PREINIT: D_imp_dbh(dbh); PPCODE: /* Verify what is passed in is a $dbh object */ if ( ! sv_derived_from(ST(0), DBI::db)) { Perl_croak(aTHX_ dbh is not of type DBI::db); } mXPUSHi( (IV) imp_dbh-envhp ); /* Environment handle */ mXPUSHi( (IV) imp_dbh-svchp ); /* Service Context handle */ mXPUSHi( (IV) imp_dbh-srvhp ); /* Server handle */ mXPUSHi( (IV) imp_dbh-authp ); /* Session handle */ XSRETURN(4); Then my idea is to use this in Perl space... my($envhp, $svchp, $srvhp, $authp) = $dbh-ora_oci_handles(); # Now share the OCI handles from DBI with the custom # C++ libraries. my $cpp_dbh = MyCppOracleClass-new(); # creates custom C++ object $cpp_dbh-envhp($envhp); $cpp_dbh-svchp($svchp); $cpp_dbh-srvhp($srvhp); $cpp_dbh-authp($authp); # Do something interesting with the C++ object $cpp_dbh-make_legacy_call_to_db(); Yup that should work I didn't put two and two together and figure you already had XS for the C++. It could be something we could add to DBD::Oracle but I would return all of the handles not just the few you need. I wonder how much it would be used though?? Cheers Quoting Martin J. Evans (martin.ev...@easysoft.com): On 27/10/2011 17:43, John Scoles wrote: Hmm!! Well yes could be done but not as part of any release of DBD::Oracle it would have to be you own hacked version Why is that John? What is the problem with returning a C pointer via a DBD::Oracle attribute? It is just a pointer to some memory and loads of XS modules do this. There is an Oracle OCI module I played with for a short time but it is problematic to build. I looked at it as I could implement OCI calls separately from DBD::Oracle. I don't seem the harm in exposing OCI handles via DBD::Oracle - it would be useful for people like the OP. A few pointers to start. You will not be able to 'get' a handle and retrun it as a Scalar it will only ever be a pointer so you will just get some sort of number, You would simly edit the Oracle.xs file add in the includes to your C++ .h files then add a few extra 'ora_' functions to take care of you C++ calls; A quick example void ora_some_c_call(dbh) SV *dbh PREINIT: D_imp_dbh(dbh); //this gets all the OCI handles for you (see dbdimp.h for the sturct imp_dbh_st) CODE: MYSomeC_Plus_Plus_method(dbh-envhp,dbh-svchp,dbh-seshp,dbh-srvhp); He does not need to do this surely. So long as the C++ code and DBD::Oracle XS is running in the same process the pointers obtained from DBD::Oracle are just as valid in the C++ code as XS. However, if the code is multi-threaded there could be issues of multiple threads accessing the OCI handles at the same time. Myself I would write a small 'c' wrapper that would call you c++ and just a single .XS function that calls that small 'c' wrapper to fire your function. My impression was that this was already done. I quote: I have created some Perl bindings for some existing