Re: Inline::C to write a DBD ?
On Mon, Oct 20, 2003 at 07:15:11PM -0700, Dean Arnold wrote: Coupla points: 1. After (painful) experimentation with Inline::Struct, I've determined it's got some significant short comings at this time heavy sigh 2. Howver, for my purposes, with Inline::C and some clever editting (thank you TextPad!) I can emulate most of Inline::Struct and probably do so in a more code optimal fashion. 3. As for Perl vs. C code, I abstain, as I haven't visited this particular soil in some time. My only perspective is from hacking DBD::ODBC some 3 years ago for array binding, and it was kinda painful for a newbie then. 4. That being said, if your API is based on simple C primitives, Inline::C might be an attractive solution...but beware of array or non-primitive inputs! Here's the interface between Driver.xst and your code. Just implement (most of) these functions: voiddbd_init _((dbistate_t *dbistate)); int dbd_db_login _((SV *dbh, imp_dbh_t *imp_dbh, char *dbname, char *user, char *pwd)); int dbd_db_login6 _((SV *dbh, imp_dbh_t *imp_dbh, char *dbname, char *user, char *pwd, SV *attr)); int dbd_db_do _((SV *sv, char *statement)); int dbd_db_commit _((SV *dbh, imp_dbh_t *imp_dbh)); int dbd_db_rollback _((SV *dbh, imp_dbh_t *imp_dbh)); int dbd_db_disconnect _((SV *dbh, imp_dbh_t *imp_dbh)); void dbd_db_destroy_((SV *dbh, imp_dbh_t *imp_dbh)); int dbd_db_STORE_attrib _((SV *dbh, imp_dbh_t *imp_dbh, SV *keysv, SV *valuesv)); SV *dbd_db_FETCH_attrib _((SV *dbh, imp_dbh_t *imp_dbh, SV *keysv)); int dbd_st_prepare _((SV *sth, imp_sth_t *imp_sth, char *statement, SV *attribs)); int dbd_st_rows_((SV *sth, imp_sth_t *imp_sth)); int dbd_st_execute _((SV *sth, imp_sth_t *imp_sth)); int dbd_st_cancel _((SV *sth, imp_sth_t *imp_sth)); AV *dbd_st_fetch _((SV *sth, imp_sth_t *imp_sth)); int dbd_st_finish _((SV *sth, imp_sth_t *imp_sth)); void dbd_st_destroy _((SV *sth, imp_sth_t *imp_sth)); int dbd_st_STORE_attrib _((SV *sth, imp_sth_t *imp_sth, SV *keysv, SV *valuesv)); SV *dbd_st_FETCH_attrib _((SV *sth, imp_sth_t *imp_sth, SV *keysv)); int dbd_bind_ph _((SV *sth, imp_sth_t *imp_sth, SV *param, SV *value, IV sql_type, SV *attribs, int is_inout, IV maxlen)); See perldoc DBI::DBD for more info. Tim.
Re: Inline::C to write a DBD ?
I'm dealing with a *very primitive* API. It operates at a level only *slightly* above socket calls. (Which is why I wrote a Pure Perl version of the driver in the first place). Eg, in order to support simple things like placeholders, a signifcant parse of the SQL is required (the DBMS supports 2 different ways of specifying placeholders, and the API doesn't parse the SQL text to identify them). Perl regex's handle that chore much more easily (and is thus much less error prone) than any C code I could write. Likewise for marshalling the parameter data, and unmarshalling the result data. The API in question inputs/outputs only raw bit streams; pack()/unpack() certainly beats any C alternative for that purpose. I could go on with many more examples. While the list of DBD prototypes may be simple and straightforward to implement for most DBMS APIs, in my particular case, the net result would be a *lot* of fairly complex C code. By using Inline::C to create a Perl-accessible version of the API, I can minimize the amount of C code (and all the errors that would likely result) needed to do things most other more advanced APIs (eg, ODBC) already handle. As an example (*not a recommendation, only for illustrative purposes*), if I created an ODBC module in Inline::C that made all the relevant ODBC API calls available to Perl, then I can implement a large portion of DBD::ODBC in Perl, and quite likely simplify the DBD code. All that being said, I seem to have inflamed a sore nerve. I apologize for being a nuisance, and will now retire to my cave for an appropriate period of penatent self-flagellation. - Dean On Mon, Oct 20, 2003 at 07:15:11PM -0700, Dean Arnold wrote: Coupla points: 1. After (painful) experimentation with Inline::Struct, I've determined it's got some significant short comings at this time heavy sigh 2. Howver, for my purposes, with Inline::C and some clever editting (thank you TextPad!) I can emulate most of Inline::Struct and probably do so in a more code optimal fashion. 3. As for Perl vs. C code, I abstain, as I haven't visited this particular soil in some time. My only perspective is from hacking DBD::ODBC some 3 years ago for array binding, and it was kinda painful for a newbie then. 4. That being said, if your API is based on simple C primitives, Inline::C might be an attractive solution...but beware of array or non-primitive inputs! Here's the interface between Driver.xst and your code. Just implement (most of) these functions: voiddbd_init _((dbistate_t *dbistate)); int dbd_db_login _((SV *dbh, imp_dbh_t *imp_dbh, char *dbname, char *user, char *pwd)); int dbd_db_login6 _((SV *dbh, imp_dbh_t *imp_dbh, char *dbname, char *user, char *pwd, SV *attr)); int dbd_db_do _((SV *sv, char *statement)); int dbd_db_commit _((SV *dbh, imp_dbh_t *imp_dbh)); int dbd_db_rollback _((SV *dbh, imp_dbh_t *imp_dbh)); int dbd_db_disconnect _((SV *dbh, imp_dbh_t *imp_dbh)); void dbd_db_destroy_((SV *dbh, imp_dbh_t *imp_dbh)); int dbd_db_STORE_attrib _((SV *dbh, imp_dbh_t *imp_dbh, SV *keysv, SV *valuesv)); SV *dbd_db_FETCH_attrib _((SV *dbh, imp_dbh_t *imp_dbh, SV *keysv)); int dbd_st_prepare _((SV *sth, imp_sth_t *imp_sth, char *statement, SV *attribs)); int dbd_st_rows_((SV *sth, imp_sth_t *imp_sth)); int dbd_st_execute _((SV *sth, imp_sth_t *imp_sth)); int dbd_st_cancel _((SV *sth, imp_sth_t *imp_sth)); AV *dbd_st_fetch _((SV *sth, imp_sth_t *imp_sth)); int dbd_st_finish _((SV *sth, imp_sth_t *imp_sth)); void dbd_st_destroy _((SV *sth, imp_sth_t *imp_sth)); int dbd_st_STORE_attrib _((SV *sth, imp_sth_t *imp_sth, SV *keysv, SV *valuesv)); SV *dbd_st_FETCH_attrib _((SV *sth, imp_sth_t *imp_sth, SV *keysv)); int dbd_bind_ph _((SV *sth, imp_sth_t *imp_sth, SV *param, SV *value, IV sql_type, SV *attribs, int is_inout, IV maxlen)); See perldoc DBI::DBD for more info. Tim.
Re: Inline::C to write a DBD ?
On Tue, Oct 21, 2003 at 10:57:22AM -0700, Dean Arnold wrote: All that being said, I seem to have inflamed a sore nerve. Not at all. It wasn't clear what the underlying api was like. From what you describe it _would_ make sense to first implement a separate module providing a thin Perl interface to the API, and then implement a pure-perl driver that uses that. Note that that's not quite the same as Inline::C to write a DBD which was the direction your subject line took us in to start with. Tim.
Re: Inline::C to write a DBD ?
Tim Bunce wrote: On Tue, Oct 21, 2003 at 10:57:22AM -0700, Dean Arnold wrote: From what you describe it _would_ make sense to first implement a separate module providing a thin Perl interface to the API, and then implement a pure-perl driver that uses that. Dean, I'm working on the thinist possible pure-perl driver, which can hopefully be a base class at a very general level. If you want to be a test case for it, let me know. -- Jeff
Re: Inline::C to write a DBD ?
Tim Bunce wrote: On Tue, Oct 21, 2003 at 10:57:22AM -0700, Dean Arnold wrote: From what you describe it _would_ make sense to first implement a separate module providing a thin Perl interface to the API, and then implement a pure-perl driver that uses that. Dean, I'm working on the thinist possible pure-perl driver, which can hopefully be a base class at a very general level. If you want to be a test case for it, let me know. -- Jeff While I'd be interested in seeing it, and may have a use in future, I've already coded the fattest possible pure-perl drivers in DBD::Teradata and DBD::Chart, so I've got a large codebase to work with ;^) Thanks, Dean Arnold Presicient Corp. www.presicient.com