XS, Advanced XS Callback Patch For OCI, Part IX A little review
Well just another quick installment for my new chapter in XS Fun This time I am just going to review what we have gone over so far before we dive into the real fun stuff.
Now we are more than half way there at least in code changes and we have covered allot of varies subjects from general 'c' programming the very specific OCI programming and a little XS sprinkled about.
So I have shown you how to get your callback into and out of DBD::Oracle with the dbd_db_STORE_attrib and dbd_db_FETCH_attrib functions. Here we saw the use of a few XS macros to make our life a little eiaser , such as 'strEQ' a little memory management with SvREFCNT_dec and a few other.
We also saw how I used a 'c' struct (structure) to hold the pointers to my paremates and how I declared this in a '.h' or header so I could use them in other 'c' programs rather than just including them in the dbdimp.c file.
I also introduced some basic oci calls and how they are mostly calles using pointers to variables rather than variables themselves. I also was thinking ahead a modularized my code a little in case Oracle decides to expand the OCI again and give us a test to see if FAN is enables the same way we can test to see if TAF is enabled.
Finally I showed you how important it is to clean up the memory from you code as any small leak can grow to a large one given enough time.
So the next task is to set up the callback, now DBD::Oracle and most 'c' based DBD seperate the 'c' part of the code into a dbdimp.c which implements most of 'common' DBD code code and another 'c' program, oci8.c in the case of DBD::Oracle when the driver specific code is kept. Well that is the theory at lease most of the DBDs have a dbdimp.c file but things have advanced along since DBD::Oracle was first written so you will find some have stuffed everything into dbdimpl.c or into a 'XS' file. It never really was a standard more just a suggestion.
Now the next file we are going to hit is 'oci8.c' but before we do that let me explain a little on how this callback works. Now as we all know 'c' is a compile once to executable language unlike Perl that is a compile at execution time language. So 'c' needs to know when it is being compiled where the 'callback' function which sort of puts us in the Paradox of always have to know what our Perl callback is before we even write it.
Well this is impossible or at least impractical, as recompiling DBD::Oracle each time you run you script will cause you to loose all you hair eventually not to mention you sanity. Now all is not lost as we can just write a static 'c' function for the 'callback' that will be around at compile time that we just send the reference to out Perl function to and that make that function call back out to Perl.
So we are actually doing two callback one from Oracle to OCI/DBD::Oracle and then from OCI/DBD::Oracle back out to Perl. So this is where the idea of 'Context' comes into play, I had mentioned this before so now I will give a little more detail on it.
So 'Context' is the present circumstances or better 'state' of our system that we want out callback to act upon when the FAN or HA event takes place. In our circumstance we send along pointer to our Perl function we want to fire and a pointer to a reference to our present Perl program to the DBD::Oracle callback that is being invoked (called-back) when a FAN or HA event occurs along with the event itself.
We can then take this FAN/HA event and translate it into something Perl can understand and then send it back to Perl by invoking the Perl function where hopefully it would be of some use.