[prev in list] [next in list] [prev in thread] [next in thread] 

List:       dbi-dev
Subject:    DBD::ADO: constants
From:       Steffen Goeldner <s.goeldner () eurodata ! de>
Date:       2001-11-23 9:22:14
[Download RAW message or body]

Steffen Goeldner wrote:
> 
> Attached is *not* a patch - it's a first cut and a cry for help!
> I have problems mapping the ADO fields to SQL/CLI (ODBC, DBI)
> fields, especially the datatype related fields.
> I guess that the magic DBD::ADO::_determine_type_support() may
> provide part of a solution.
> Any suggestions, hints, insides, patches, ... are welcome!
> 

No, I didn't give up! I'm still playing with OpenSchema() and
investigate the results. Thereby, I encountered some difficulties
with the DBD::ADO constants ($ado_consts) - more precisely: how
they are stored.
It's easy to lookup DBD::ADO constants by name, e.g.:

  $ado_consts->{adChar} == 129

Unfortunately, Win32::OLE::Const does not preserve the namespace
of the enums. It's a matter of taste, but I think

  $ado_consts->{DataTypeEnum}{adChar} == 129

makes the code more self-documented. Furthermore, many DBD::ADO
methods return numeric codes. Transforming these codes into human
readable strings requires an inverse lookup by value. Building the
reverse hash for e.g. all datatypes requires that datatype constants
can be distinguished from other constants, i.e. we need the namespace
preserved.
The Enums() method of the attached package returns a hash of hashes
for exactly this purpose. Now you can do:

  my $Enums = Local::DBI::ADO::TypeInfo->Enums;
  my %Types = reverse %{$Enums->{DataTypeEnum}};

  my $sth = $dbh->func('adSchemaColumns', @Criteria, 'OpenSchema');
  while ( my $Row = $sth->fetch ) {
    ...
    print $Row->[11] , ' is ', $Types{$Row->[11]};  # DATA_TYPE
    ...
  }


Steffen
["TypeInfo.pm" (text/plain)]

package Local::DBI::ADO::TypeInfo;

use Win32::OLE();
use Win32::OLE::TypeInfo();

my $ProgId  = 'ADODB.Connection';
my $VarSkip = Win32::OLE::TypeInfo::VARFLAG_FHIDDEN()
            | Win32::OLE::TypeInfo::VARFLAG_FRESTRICTED()
            | Win32::OLE::TypeInfo::VARFLAG_FNONBROWSABLE()
            ;
my $Enums;

# -----------------------------------------------------------------------------
sub Enums
# -----------------------------------------------------------------------------
{
  my $class = shift;

  return $Enums if $Enums;

  my $TypeLib = Win32::OLE->new( $ProgId )->GetTypeInfo->GetContainingTypeLib;

  for my $i ( 0 .. $TypeLib->_GetTypeInfoCount - 1 )
  {
    my $TypeInfo = $TypeLib->_GetTypeInfo( $i );
    my $TypeAttr = $TypeInfo->_GetTypeAttr;
    next unless $TypeAttr->{typekind} == Win32::OLE::TypeInfo::TKIND_ENUM();
    my $Enum = $Enums->{$TypeInfo->_GetDocumentation->{Name}} = {};
    for my $i ( 0 .. $TypeAttr->{cVars} - 1 )
    {
      my $VarDesc = $TypeInfo->_GetVarDesc( $i );
      next if $VarDesc->{wVarFlags} & $VarSkip;
      my $Documentation = $TypeInfo->_GetDocumentation( $VarDesc->{memid} );
      $Enum->{$Documentation->{Name}} = $VarDesc->{varValue};
    }
  }
  return $Enums;
}
# -----------------------------------------------------------------------------
__PACKAGE__;

=head1 NAME

Local::DBI::ADO::TypeInfo - ADO TypeInfo

=head1 SYNOPSIS

  use Local::DBI::ADO::TypeInfo();

  $\ = "\n";

  my $Enums = Local::DBI::ADO::TypeInfo->Enums;

  for my $Enum ( sort keys %$Enums )
  {
    print $Enum;
    for my $Const ( sort keys %{$Enums->{$Enum}} )
    {
      printf "  %-35s 0x%X\n", $Const, $Enums->{$Enum}{$Const};
    }
  }

=cut


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic