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 this....probably 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 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
> > > > >>>
> > > > > 
> > > > 
> >                                       
> 

Reply via email to