$VERSION
=
'0.03'
;
$ODBCPackage
=
"Win32::ODBC"
;
$ODBCPackage::Version
= 970208;
$::ODBC =
$ODBCPackage
;
$CacheConnection
= 0;
*ODBC::
=\
%Win32::ODBC::
;
@ISA
=
qw( Exporter DynaLoader )
;
@EXPORT
=
qw(
ODBC_ADD_DSN
ODBC_REMOVE_DSN
ODBC_CONFIG_DSN
SQL_DONT_CLOSE
SQL_DROP
SQL_CLOSE
SQL_UNBIND
SQL_RESET_PARAMS
SQL_FETCH_NEXT
SQL_FETCH_FIRST
SQL_FETCH_LAST
SQL_FETCH_PRIOR
SQL_FETCH_ABSOLUTE
SQL_FETCH_RELATIVE
SQL_FETCH_BOOKMARK
SQL_COLUMN_COUNT
SQL_COLUMN_NAME
SQL_COLUMN_TYPE
SQL_COLUMN_LENGTH
SQL_COLUMN_PRECISION
SQL_COLUMN_SCALE
SQL_COLUMN_DISPLAY_SIZE
SQL_COLUMN_NULLABLE
SQL_COLUMN_UNSIGNED
SQL_COLUMN_MONEY
SQL_COLUMN_UPDATABLE
SQL_COLUMN_AUTO_INCREMENT
SQL_COLUMN_CASE_SENSITIVE
SQL_COLUMN_SEARCHABLE
SQL_COLUMN_TYPE_NAME
SQL_COLUMN_TABLE_NAME
SQL_COLUMN_OWNER_NAME
SQL_COLUMN_QUALIFIER_NAME
SQL_COLUMN_LABEL
SQL_COLATT_OPT_MAX
SQL_COLUMN_DRIVER_START
SQL_COLATT_OPT_MIN
SQL_ATTR_READONLY
SQL_ATTR_WRITE
SQL_ATTR_READWRITE_UNKNOWN
SQL_UNSEARCHABLE
SQL_LIKE_ONLY
SQL_ALL_EXCEPT_LIKE
SQL_SEARCHABLE
)
;
sub
new
{
my
(
$n
,
$self
);
my
(
$type
) =
shift
;
my
(
$DSN
) =
shift
;
my
(
@Results
) =
@_
;
if
(
ref
$DSN
){
@Results
= ODBCClone(
$DSN
->{
'connection'
});
}
else
{
@Results
= ODBCConnect(
$DSN
,
@Results
);
}
@Results
= processError(-1,
@Results
);
if
(!
scalar
(
@Results
)){
return
undef
;
}
$self
=
bless
{};
$self
->{
'connection'
} =
$Results
[0];
$ErrConn
=
$Results
[0];
$ErrText
=
$Results
[1];
$ErrNum
= 0;
$self
->{
'DSN'
} =
$DSN
;
$self
;
}
sub
Close
{
my
(
$self
,
$Result
) =
shift
;
$Result
= DESTROY(
$self
);
$self
->{
'connection'
} = -1;
return
$Result
;
}
sub
DESTROY
{
my
(
$self
) =
shift
;
my
(
@Results
) = (0);
if
(
$self
->{
'connection'
} > -1){
@Results
= ODBCDisconnect(
$self
->{
'connection'
});
@Results
= processError(
$self
,
@Results
);
if
(
$Results
[0]){
undef
$self
->{
'DSN'
};
undef
@{
$self
->{
'fnames'
}};
undef
%{
$self
->{
'field'
}};
undef
%{
$self
->{
'connection'
}};
}
}
return
$Results
[0];
}
sub
sql{
return
(Sql(
@_
));
}
sub
Sql{
my
(
$self
,
$Sql
,
@Results
) =
@_
;
@Results
= ODBCExecute(
$self
->{
'connection'
},
$Sql
);
return
updateResults(
$self
,
@Results
);
}
sub
Data{
my
(
$self
) =
shift
;
my
(
@Fields
) =
@_
;
my
(
@Results
,
$Results
,
$Field
);
if
(
$self
->{
'Dirty'
}){
GetData(
$self
);
$self
->{
'Dirty'
} = 0;
}
@Fields
= @{
$self
->{
'fnames'
}}
if
(!
scalar
(
@Fields
));
foreach
$Field
(
@Fields
) {
if
(
wantarray
) {
push
(
@Results
, data(
$self
,
$Field
));
}
else
{
$Results
.= data(
$self
,
$Field
);
}
}
return
wantarray
?
@Results
:
$Results
;
}
sub
DataHash{
my
(
$self
,
@Results
) =
@_
;
my
(
%Results
,
$Element
);
if
(
$self
->{
'Dirty'
}){
GetData(
$self
);
$self
->{
'Dirty'
} = 0;
}
@Results
= @{
$self
->{
'fnames'
}}
if
(!
scalar
(
@Results
));
foreach
$Element
(
@Results
) {
$Results
{
$Element
} = data(
$self
,
$Element
);
}
return
%Results
;
}
sub
data
{
$_
[0]->{
'data'
}->{
$_
[1]}; }
sub
fetchrow{
return
(FetchRow(
@_
));
}
sub
FetchRow{
my
(
$self
,
@Results
) =
@_
;
my
(
$item
,
$num
,
$sqlcode
);
$num
= 0;
undef
$self
->{
'data'
};
@Results
= ODBCFetch(
$self
->{
'connection'
},
@Results
);
if
(! (
@Results
= processError(
$self
,
@Results
))){
return
undef
;
}
$self
->{
'Dirty'
} = 1;
return
@Results
;
}
sub
GetData{
my
(
$self
) =
@_
;
my
(
@Results
,
$num
);
@Results
= ODBCGetData(
$self
->{
'connection'
});
if
(!(
@Results
= processError(
$self
,
@Results
))){
return
undef
;
}
ClearError();
foreach
(
@Results
){
s/ +$//;
$self
->{
'data'
}->{ ${
$self
->{
'fnames'
}}[
$num
] } =
$_
;
$num
++;
}
return
wantarray
? (1, 1): 1;
}
sub
MoreResults{
my
(
$self
) =
@_
;
my
(
@Results
) = ODBCMoreResults(
$self
->{
'connection'
});
return
(processError(
$self
,
@Results
))[0];
}
sub
Catalog{
my
(
$self
) =
shift
;
my
(
$Qualifier
,
$Owner
,
$Name
,
$Type
) =
@_
;
my
(
@Results
) = ODBCTableList(
$self
->{
'connection'
},
$Qualifier
,
$Owner
,
$Name
,
$Type
);
return
(updateResults(
$self
,
@Results
) != 1);
}
sub
TableList{
my
(
$self
) =
shift
;
my
(
@Results
) =
@_
;
if
(!
scalar
(
@Results
)){
@Results
= (
""
,
""
,
"%"
,
"TABLE"
);
}
if
(! Catalog(
$self
,
@Results
)){
return
undef
;
}
undef
@Results
;
while
(FetchRow(
$self
)){
push
(
@Results
, Data(
$self
,
"TABLE_NAME"
));
}
return
sort
(
@Results
);
}
sub
fieldnames{
return
(FieldNames(
@_
));
}
sub
FieldNames {
$self
=
shift
;
return
@{
$self
->{
'fnames'
}}; }
sub
ShutDown{
my
(
$self
) =
@_
;
print
"\nClosing connection $self->{'connection'}..."
;
$self
->Close();
print
"\nDone\n"
;
}
sub
Connection{
my
(
$self
) =
@_
;
return
$self
->{
'connection'
};
}
sub
GetConnections{
return
ODBCGetConnections();
}
sub
SetMaxBufSize{
my
(
$self
,
$Size
) =
@_
;
my
(
@Results
) = ODBCSetMaxBufSize(
$self
->{
'connection'
},
$Size
);
return
(processError(
$self
,
@Results
))[0];
}
sub
GetMaxBufSize{
my
(
$self
) =
@_
;
my
(
@Results
) = ODBCGetMaxBufSize(
$self
->{
'connection'
});
return
(processError(
$self
,
@Results
))[0];
}
sub
GetDSN{
my
(
$self
,
$DSN
) =
@_
;
if
(!
ref
(
$self
)){
$DSN
=
$self
;
$self
= 0;
}
if
(!
$DSN
){
$self
=
$self
->{
'connection'
};
}
my
(
@Results
) = ODBCGetDSN(
$self
,
$DSN
);
return
(processError(
$self
,
@Results
));
}
sub
DataSources{
my
(
$self
,
$DSN
) =
@_
;
if
(!
ref
$self
){
$DSN
=
$self
;
$self
= 0;
}
my
(
@Results
) = ODBCDataSources(
$DSN
);
return
(processError(
$self
,
@Results
));
}
sub
Drivers{
my
(
$self
) =
@_
;
if
(!
ref
$self
){
$self
= 0;
}
my
(
@Results
) = ODBCDrivers();
return
(processError(
$self
,
@Results
));
}
sub
RowCount{
my
(
$self
,
$Connection
) =
@_
;
if
(!
ref
(
$self
)){
$Connection
=
$self
;
$self
= 0;
}
if
(!
$Connection
){
$Connection
=
$self
->{
'connection'
};}
my
(
@Results
) = ODBCRowCount(
$Connection
);
return
(processError(
$self
,
@Results
))[0];
}
sub
GetStmtCloseType{
my
(
$self
,
$Connection
) =
@_
;
if
(!
ref
(
$self
)){
$Connection
=
$self
;
$self
= 0;
}
if
(!
$Connection
){
$Connection
=
$self
->{
'connection'
};}
my
(
@Results
) = ODBCGetStmtCloseType(
$Connection
);
return
(processError(
$self
,
@Results
));
}
sub
SetStmtCloseType{
my
(
$self
,
$Type
,
$Connection
) =
@_
;
if
(!
ref
(
$self
)){
$Connection
=
$Type
;
$Type
=
$self
;
$self
= 0;
}
if
(!
$Connection
){
$Connection
=
$self
->{
'connection'
};}
my
(
@Results
) = ODBCSetStmtCloseType(
$Connection
,
$Type
);
return
(processError(
$self
,
@Results
))[0];
}
sub
ColAttributes{
my
(
$self
,
$Type
,
@Field
) =
@_
;
my
(
%Results
,
@Results
,
$Results
,
$Attrib
,
$Connection
,
$Temp
);
if
(!
ref
(
$self
)){
$Type
=
$Field
;
$Field
=
$self
;
$self
= 0;
}
$Connection
=
$self
->{
'connection'
};
if
(!
scalar
(
@Field
)){
@Field
=
$self
->fieldnames;}
foreach
$Temp
(
@Field
){
@Results
= ODBCColAttributes(
$Connection
,
$Temp
,
$Type
);
(
$Attrib
) = processError(
$self
,
@Results
);
if
(
wantarray
){
$Results
{
$Temp
} =
$Attrib
;
}
else
{
$Results
.=
"$Temp"
;
}
}
return
wantarray
?
%Results
:
$Results
;
}
sub
GetInfo{
my
(
$self
,
$Type
) =
@_
;
my
(
$Connection
,
@Results
);
if
(!
ref
$self
){
$Type
=
$self
;
$self
= 0;
$Connection
= 0;
}
else
{
$Connection
=
$self
->{
'connection'
};
}
@Results
= ODBCGetInfo(
$Connection
,
$Type
);
return
(processError(
$self
,
@Results
))[0];
}
sub
GetConnectOption{
my
(
$self
,
$Type
) =
@_
;
my
(
@Results
);
if
(!
ref
$self
){
$Type
=
$self
;
$self
= 0;
}
@Results
= ODBCGetConnectOption(
$self
->{
'connection'
},
$Type
);
return
(processError(
$self
,
@Results
))[0];
}
sub
SetConnectOption{
my
(
$self
,
$Type
,
$Value
) =
@_
;
if
(!
ref
$self
){
$Value
=
$Type
;
$Type
=
$self
;
$self
= 0;
}
my
(
@Results
) = ODBCSetConnectOption(
$self
->{
'connection'
},
$Type
,
$Value
);
return
(processError(
$self
,
@Results
))[0];
}
sub
Transact{
my
(
$self
,
$Type
) =
@_
;
my
(
@Results
);
if
(!
ref
$self
){
$Type
=
$self
;
$self
= 0;
}
@Results
= ODBCTransact(
$self
->{
'connection'
},
$Type
);
return
(processError(
$self
,
@Results
))[0];
}
sub
SetPos{
my
(
$self
,
@Results
) =
@_
;
@Results
= ODBCSetPos(
$self
->{
'connection'
},
@Results
);
$self
->{
'Dirty'
} = 1;
return
(processError(
$self
,
@Results
))[0];
}
sub
ConfigDSN{
my
(
$self
) =
shift
@_
;
my
(
$Type
,
$Connection
);
if
(!
ref
$self
){
$Type
=
$self
;
$Connection
= 0;
$self
= 0;
}
else
{
$Type
=
shift
@_
;
$Connection
=
$self
->{
'connection'
};
}
my
(
$Driver
,
@Attributes
) =
@_
;
@Results
= ODBCConfigDSN(
$Connection
,
$Type
,
$Driver
,
@Attributes
);
return
(processError(
$self
,
@Results
))[0];
}
sub
Version{
my
(
$self
,
@Packages
) =
@_
;
my
(
$Temp
,
@Results
);
if
(!
ref
(
$self
)){
push
(
@Packages
,
$self
);
}
my
(
$ExtName
,
$ExtVersion
) = Info();
if
(!
scalar
(
@Packages
)){
@Packages
= (
"ODBC.PM"
,
"ODBC.PLL"
);
}
foreach
$Temp
(
@Packages
){
if
(
$Temp
=~ /pll/i){
push
(
@Results
,
"ODBC.PM:$Win32::ODBC::Version"
);
}
elsif
(
$Temp
=~ /pm/i){
push
(
@Results
,
"ODBC.PLL:$ExtVersion"
);
}
}
return
@Results
;
}
sub
SetStmtOption{
my
(
$self
,
$Option
,
$Value
) =
@_
;
if
(!
ref
$self
){
$Value
=
$Option
;
$Option
=
$self
;
$self
= 0;
}
my
(
@Results
) = ODBCSetStmtOption(
$self
->{
'connection'
},
$Option
,
$Value
);
return
(processError(
$self
,
@Results
))[0];
}
sub
GetStmtOption{
my
(
$self
,
$Type
) =
@_
;
if
(!
ref
$self
){
$Type
=
$self
;
$self
= 0;
}
my
(
@Results
) = ODBCGetStmtOption(
$self
->{
'connection'
},
$Type
);
return
(processError(
$self
,
@Results
))[0];
}
sub
GetFunctions{
my
(
$self
,
@Results
)=
@_
;
@Results
= ODBCGetFunctions(
$self
->{
'connection'
},
@Results
);
return
(processError(
$self
,
@Results
));
}
sub
DropCursor{
my
(
$self
) =
@_
;
my
(
@Results
) = ODBCDropCursor(
$self
->{
'connection'
});
return
(processError(
$self
,
@Results
))[0];
}
sub
SetCursorName{
my
(
$self
,
$Name
) =
@_
;
my
(
@Results
) = ODBCSetCursorName(
$self
->{
'connection'
},
$Name
);
return
(processError(
$self
,
@Results
))[0];
}
sub
GetCursorName{
my
(
$self
) =
@_
;
my
(
@Results
) = ODBCGetCursorName(
$self
->{
'connection'
});
return
(processError(
$self
,
@Results
))[0];
}
sub
GetSQLState{
my
(
$self
) =
@_
;
my
(
@Results
) = ODBCGetSQLState(
$self
->{
'connection'
});
return
(processError(
$self
,
@Results
))[0];
}
sub
updateResults{
my
(
$self
,
$Error
,
@Results
) =
@_
;
undef
%{
$self
->{
'field'
}};
ClearError(
$self
);
if
(
$Error
){
SetError(
$self
,
$Results
[0],
$Results
[1]);
return
(
$Error
);
}
@{
$self
->{
'fnames'
}} =
@Results
;
foreach
(0..$
s/ +$//;
$self
->{
'field'
}->{${
$self
->{
'fnames'
}}[
$_
]} =
$_
;
}
return
undef
;
}
sub
Debug{
my
(
$self
,
$iDebug
,
$File
) =
@_
;
my
(
@Results
);
if
(!
ref
(
$self
)){
if
(
defined
$self
){
$File
=
$iDebug
;
$iDebug
=
$self
;
}
$Connection
= 0;
$self
= 0;
}
else
{
$Connection
=
$self
->{
'connection'
};
}
push
(
@Results
, (
$Connection
,
$iDebug
));
push
(
@Results
,
$File
)
if
(
$File
ne
""
);
@Results
= ODBCDebug(
@Results
);
return
(processError(
$self
,
@Results
))[0];
}
sub
DumpData {
my
(
$self
) =
@_
;
my
(
$f
,
$goo
);
print
"\nDumping Data for connection: $self->{'connection'}\n"
;
print
"Error: \""
;
print
$self
->Error();
print
"\"\n"
;
if
(!
$self
->Error()){
foreach
$f
(
$self
->FieldNames){
print
$f
.
" "
;
$goo
.=
"-"
x
length
(
$f
);
$goo
.=
" "
;
}
print
"\n$goo\n"
;
while
(
$self
->FetchRow()){
foreach
$f
(
$self
->FieldNames){
print
$self
->data(
$f
) .
" "
;
}
print
"\n"
;
}
}
}
sub
DumpError{
my
(
$self
) =
@_
;
my
(
$ErrNum
,
$ErrText
,
$ErrConn
);
my
(
$Temp
);
print
"\n---------- Error Report: ----------\n"
;
if
(
ref
$self
){
(
$ErrNum
,
$ErrText
,
$ErrConn
) =
$self
->Error();
(
$Temp
=
$self
->GetDSN()) =~ s/.
*DSN
=(.*?);.*/$1/i;
print
"Errors for \"$Temp\" on connection "
.
$self
->{
'connection'
} .
":\n"
;
}
else
{
(
$ErrNum
,
$ErrText
,
$ErrConn
) = Error();
print
"Errors for the package:\n"
;
}
print
"Connection Number: $ErrConn\nError number: $ErrNum\nError message: \"$ErrText\"\n"
;
print
"-----------------------------------\n"
;
}
sub
Run{
my
(
$self
,
$Sql
) =
@_
;
print
"\nExcecuting connection $self->{'connection'}\nsql statement: \"$Sql\"\n"
;
$self
->sql(
$Sql
);
print
"Error: \""
;
print
$self
->error;
print
"\"\n"
;
print
"--------------------\n\n"
;
}
sub
processError{
my
(
$self
,
$Error
,
@Results
) =
@_
;
if
(
$Error
){
SetError(
$self
,
$Results
[0],
$Results
[1]);
undef
@Results
;
}
return
@Results
;
}
sub
error{
return
(Error(
@_
));
}
sub
Error{
my
(
$self
) =
@_
;
if
(
ref
(
$self
)){
if
(
$self
->{
'ErrNum'
}){
my
(
$State
) = ODBCGetSQLState(
$self
->{
'connection'
});
return
(
wantarray
)? (
$self
->{
'ErrNum'
},
$self
->{
'ErrText'
},
$self
->{
'connection'
},
$State
) :
"[$self->{'ErrNum'}] [$self->{'connection'}] [$State] \"$self->{'ErrText'}\""
;
}
}
elsif
(
$ErrNum
){
return
(
wantarray
)? (
$ErrNum
,
$ErrText
,
$ErrConn
):
"[$ErrNum] [$ErrConn] \"$ErrText\""
;
}
return
undef
}
sub
SetError{
my
(
$self
,
$Num
,
$Text
,
$Conn
) =
@_
;
if
(
ref
$self
){
$self
->{
'ErrNum'
} =
$Num
;
$self
->{
'ErrText'
} =
$Text
;
$Conn
=
$self
->{
'connection'
}
if
!
$Conn
;
}
$ErrNum
=
$Num
;
$ErrText
=
$Text
;
$ErrConn
=
$Conn
;
}
sub
ClearError{
my
(
$self
,
$Num
,
$Text
) =
@_
;
if
(
ref
$self
){
undef
$self
->{
'ErrNum'
};
undef
$self
->{
'ErrText'
};
}
else
{
undef
$ErrConn
;
undef
$ErrNum
;
undef
$ErrText
;
}
ODBCCleanError();
return
1;
}
sub
GetError{
my
(
$self
,
$Connection
) =
@_
;
my
(
@Results
);
if
(!
ref
(
$self
)){
$Connection
=
$self
;
$self
= 0;
}
else
{
if
(!
defined
(
$Connection
)){
$Connection
=
$self
->{
'connection'
};
}
}
@Results
= ODBCGetError(
$Connection
);
return
@Results
;
}
sub
AUTOLOAD {
my
(
$constname
);
(
$constname
=
$AUTOLOAD
) =~ s/.*:://;
$!=0;
$val
= constant(
$constname
,
@_
?
$_
[0] : 0);
if
($! != 0) {
if
($! =~ /Invalid/) {
$AutoLoader::AUTOLOAD
=
$AUTOLOAD
;
goto
&AutoLoader::AUTOLOAD
;
}
else
{
$pack
= 0;
(
$pack
,
$file
,
$line
) =
caller
;
print
"Your vendor has not defined Win32::ODBC macro $constname, used in $file at line $line."
;
}
}
eval
"sub $AUTOLOAD { $val }"
;
goto
&$AUTOLOAD
;
}
END{
}
bootstrap Win32::ODBC;
1;