use
vars
qw[ $DEBUG $VERSION @EXPORT_OK ]
;
$VERSION
=
'1.59'
;
$DEBUG
= 0
unless
defined
$DEBUG
;
no
strict
'refs'
;
sub
parse {
my
(
$tr
,
$dbh
) =
@_
;
if
(
$dbh
->{FetchHashKeyName} ne
'NAME_uc'
) {
warn
"setting dbh attribute {FetchHashKeyName} to NAME_uc"
;
$dbh
->{FetchHashKeyName} =
'NAME_uc'
;
}
if
(
$dbh
->{ChopBlanks} != 1) {
warn
"setting dbh attribute {ChopBlanks} to 1"
;
$dbh
->{ChopBlanks} = 1;
}
my
$schema
=
$tr
->schema;
my
(
$sth
,
@tables
,
$columns
);
my
$stuff
;
$sth
=
$dbh
->column_info(
undef
,
undef
,
undef
,
undef
);
foreach
my
$c
(@{
$sth
->fetchall_arrayref({})}) {
$columns
->{
$c
->{TABLE_CAT}}
->{
$c
->{TABLE_SCHEM}}
->{
$c
->{TABLE_NAME}}
->{columns}
->{
$c
->{COLUMN_NAME}}=
$c
;
}
$sth
=
$dbh
->table_info();
@tables
= @{
$sth
->fetchall_arrayref({})};
my
$h
=
$dbh
->selectall_arrayref(
q{
SELECT o.name, colid,c.text
FROM syscomments c
JOIN sysobjects o
ON c.id = o.id
WHERE o.type ='V'
ORDER BY o.name,
c.colid
}
);
foreach
(@{
$h
}) {
$stuff
->{view}->{
$_
->[0]}->{text} .=
$_
->[2];
}
map
{
$stuff
->{indexes}->{
$_
->[0]}++
if
defined
;
} @{
$dbh
->selectall_arrayref("SELECT DISTINCT object_name(id)
FROM sysindexes
WHERE indid > 0 and indid < 255 and
name not like
'_WA_Sys%'
")};
map
{
$stuff
->{
$_
->[1]}->{
$_
->[0]} =
$_
;
} @{
$dbh
->selectall_arrayref(
"SELECT name,type, id FROM sysobjects"
)};
map
{
my
$n
=
$_
->{PROCEDURE_NAME};
$n
=~ s/;\d+$//;
$_
->{name} =
$n
;
$stuff
->{procedures}->{
$n
} =
$_
;
}
values
%{
$dbh
->selectall_hashref(
"sp_stored_procedures"
,
'PROCEDURE_NAME'
)};
$h
=
$dbh
->selectall_arrayref(
q{
SELECT o.name, colid,c.text
FROM syscomments c
JOIN sysobjects o
ON c.id = o.id
WHERE o.type in ('P', 'FN', 'TF', 'IF')
}
);
foreach
(@{
$h
}) {
$stuff
->{procedures}->{
$_
->[0]}->{text} .=
$_
->[2]
if
(
defined
(
$stuff
->{procedures}->{
$_
->[0]}));
}
$h
=
$dbh
->selectall_arrayref(
q{
SELECT o.name, colid,c.text
FROM syscomments c
JOIN sysobjects o
ON c.id = o.id
JOIN sysobjects o1
ON (o.id = o1.instrig OR o.id = o1.deltrig or o.id = o1.updtrig)
WHERE o.type ='TR'
ORDER BY o.name,
c.colid
}
);
foreach
(@{
$h
}) {
$stuff
->{triggers}->{
$_
->[0]}->{text} .=
$_
->[2];
}
$stuff
->{type_info_all} =
$dbh
->type_info_all;
foreach
my
$table_info
(
@tables
) {
next
unless
(
defined
(
$table_info
->{TABLE_TYPE}));
if
(
$table_info
->{TABLE_TYPE} eq
"TABLE"
) {
my
$table
=
$schema
->add_table(
name
=>
$table_info
->{TABLE_NAME},
type
=>
$table_info
->{TABLE_TYPE},
) ||
die
$schema
->error;
my
$cols
=
$columns
->{
$table_info
->{TABLE_CAT}}
->{
$table_info
->{TABLE_SCHEM}}
->{
$table_info
->{TABLE_NAME}}
->{columns};
foreach
my
$c
(
values
%{
$cols
}) {
my
$is_auto_increment
=
$c
->{TYPE_NAME} =~ s
my
$f
=
$table
->add_field(
name
=>
$c
->{COLUMN_NAME},
data_type
=>
$c
->{TYPE_NAME},
order
=>
$c
->{ORDINAL_POSITION},
size
=>
$c
->{COLUMN_SIZE},
) ||
die
$table
->error;
$f
->is_nullable(
$c
->{NULLABLE} == 1);
$f
->is_auto_increment(
$is_auto_increment
);
if
(
defined
$c
->{COLUMN_DEF}) {
$c
->{COLUMN_DEF} =~ s
$f
->default_value(
$c
->{COLUMN_DEF});
}
}
my
$h
=
$dbh
->selectall_hashref("sp_pkeys
$table_info
->{TABLE_NAME}",
'COLUMN_NAME'
);
if
(
scalar
keys
%{
$h
} >= 1) {
my
@c
=
map
{
$_
->{COLUMN_NAME}
}
sort
{
$a
->{KEY_SEQ} <=>
$b
->{KEY_SEQ}
}
values
%{
$h
};
$table
->primary_key(
@c
)
if
(
scalar
@c
);
}
$h
=
$dbh
->selectall_hashref("sp_fkeys NULL,
\
@fktable_name
=
'$table_info->{TABLE_NAME}'
",
'FK_NAME'
);
foreach
my
$fk
(
values
%{
$h
} ) {
my
$constraint
=
$table
->add_constraint(
name
=>
$fk
->{FK_NAME},
fields
=> [
$fk
->{FKCOLUMN_NAME}],
);
$constraint
->type(
"FOREIGN_KEY"
);
$constraint
->on_delete(
$fk
->{DELETE_RULE} == 0 ?
"CASCADE"
:
$fk
->{DELETE_RULE} == 1 ?
"NO ACTION"
:
"SET_NULL"
);
$constraint
->on_update(
$fk
->{UPDATE_RULE} == 0 ?
"CASCADE"
:
$fk
->{UPDATE_RULE} == 1 ?
"NO ACTION"
:
"SET_NULL"
);
$constraint
->reference_table(
$fk
->{PKTABLE_NAME});
}
if
(
defined
(
$stuff
->{indexes}->{
$table_info
->{TABLE_NAME}})){
my
$h
=
$dbh
->selectall_hashref("sp_helpindex
$table_info
->{TABLE_NAME}",
'INDEX_NAME'
);
foreach
(
values
%{
$h
}) {
my
$fields
=
$_
->{
'INDEX_KEYS'
};
$fields
=~ s/\s*//g;
my
$i
=
$table
->add_index(
name
=>
$_
->{INDEX_NAME},
fields
=>
$fields
,
);
if
(
$_
->{
'INDEX_DESCRIPTION'
} =~ /unique/i) {
$i
->type(
'unique'
);
if
(!
defined
(
$table
->primary_key())) {
$table
->primary_key(
$fields
)
unless
grep
{
$table
->get_field(
$_
)->is_nullable()
}
split
(/,\s*/,
$fields
);
}
}
}
}
}
elsif
(
$table_info
->{TABLE_TYPE} eq
'VIEW'
) {
next
if
$table_info
->{TABLE_NAME} eq
'sysconstraints'
||
$table_info
->{TABLE_NAME} eq
'syssegments'
;
next
if
!
$stuff
->{view}->{
$table_info
->{TABLE_NAME}}->{text};
my
$view
=
$schema
->add_view(
name
=>
$table_info
->{TABLE_NAME},
);
my
$cols
=
$columns
->{
$table_info
->{TABLE_CAT}}
->{
$table_info
->{TABLE_SCHEM}}
->{
$table_info
->{TABLE_NAME}}
->{columns};
$view
->fields(
map
{
$_
->{COLUMN_NAME}
}
sort
{
$a
->{ORDINAL_POSITION} <=>
$b
->{ORDINAL_POSITION}
}
values
%{
$cols
}
);
$view
->sql(
$stuff
->{view}->{
$table_info
->{TABLE_NAME}}->{text})
if
(
defined
(
$stuff
->{view}->{
$table_info
->{TABLE_NAME}}->{text}));
}
}
foreach
my
$p
(
values
%{
$stuff
->{procedures}}) {
next
if
!
$p
->{text};
my
$proc
=
$schema
->add_procedure(
name
=>
$p
->{name},
owner
=>
$p
->{PROCEDURE_OWNER},
comments
=>
$p
->{REMARKS},
sql
=>
$p
->{text},
);
}
return
1;
}
1;