I tried to subclass DDL::Oracle, because I wanted to change some behaviour. I
ran across the problem that most global variables were lexically scoped and
thus not accessible from another file.
I am not 100% sure about this, but it seems to me, that global my variables are
problematic, when it comes to subclassing.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It would be helpful to us if you would describe the behaviour you are trying to change. Perhaps there are alternatives.
In Perl terms, DDL::Oracle is strictly OO -- it exports nothing. Its only interface is through the 2 Class methods plus the 5 Object methods. As such, I don't think you can subclass it. But maybe you should explain what *you* mean by "subclass."
You can, of course, operate on the output (e.g., remove the heading (REM's), alter the table/index names, etc. In fact, defrag.pl does this with some of DDL::Oracle's output.
If it is the DDL itself you want to alter, maybe you have found a bug(s). If this is the case, please describe the circumstances.
But mainly, we are interested in what it is you want to change, because there may be others with the same ideas and the changes could be incorporated into the module for all to enjoy.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
(1) The _set_sizing() method require access to
v$parameter. Even if I only want to look at
some package code, I need this privilege. I
cannot even get past configure though.
(2) I would like to get PACKAGE and PACKAGE BODY
independently. If I want both I'd rather have
a _get_package_family command.
(3) I found that the 3 lines in a trigger
description sometimes come in a single
line, so the parsing done in _create_trigger
sometimes fails to produce correct syntax. I
can provide a patch.
By subclassing I mean, I wanted to create a
derived class, that has some methods changed
(_create_package, _create_trgger, _get_sizing).
I could not do this because I would have to
access my $dbh, which is not accessible from
outside of DDL::Oracle.
IMHO there should be no global my variables.
They should be either instance variables or
true class variables (I may be wrong though).
In either case you still would not export
anything.
Yes I am removing the REMs the way defrag.pl does
it, even though I'd rather have a "quiet" option.
But this is really not important and it would
require a lot of ifs in the code of DDL::Oracle.
As mentioned before, I think DDL::Oracle is a
wonderful program and it could be the basis for
a lot of useful tools.
BTW: what I am trying to do is to write a
sqlplus replacement (yes, another one), that
is sqlplus compliant and that has a lot of
additional commands (such as PULL PACKAGE -
get the code of a package. This of course
uses DDL::Oracle). The tool will be called
"Senora".
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thank you very much for taking the time to submit these comments. I have included 3 of them in the just released Version 1.03. See the Change Log below.
Let's talk about the requirement that the user have access to V$PARAMETER. The 'create' and 'resize' methods for Tables and Indexes include the STORAGE clause entries for INITIAL and NEXT. Some of the Dictionary views hold these values as the number of database blocks. Thus, it is necessary that DDL::Oracle multiply these values by the bytes in the init.ora parameter 'db_block_size'. The only alternative to issuing this query would be to add another config attribute where the user could specify the block size. I am reluctant to do this for 2 reasons. First, I think most users use DDL::Oracle to generate DDL for Tables and Indexes, and that they would prefer not to have to enter this argument. Second, views V$VERSION and V$DATABASE are also accessed -- this is necessary because three Releases of Oracle are supported (7.3, 8.0 and 8i). I also believe (but have no imperical evidence) that access to the V$ views is commonplace. If your DBA's won't give you this access, tell them I said it was OK ;-)
Now, about subclassing. One of the primary benefits of Object Oriented programming is that the users don't have to concern themselves with the inner workings of the Class (module, in Perl's terms). All you have to do is deal with the public interface which, in the case of DDL::Oracle, is pretty simple (IMHO). You wanted to be able to "access my $dbh which is not accessible from outside". But, of course, it IS accessible from outside -- the user program is responsible for obtaining the connection to Oracle, and for passing it into DDL::Oracle for its use. So I'm not sure you have the problem you thought you did.
If you still disagree, add some more ammunition to your argument, and I'll consider it some more.
Cheers.
Richard
----------------
CHANGES (in 1.03)
Rewrote routine for CREATE TRIGGER, which was buggy, farkled and less
than a stellar effort. Added support for SCHEMA and DATABASE triggers.
Separated CREATE PACKAGE BODY from the CREATE PACKAGE function, giving
it its own function. Apologies to users who may have scripts which
rely on the original behavior -- you will need to adapt them if you
upgrade to 1.03 and beyond.
Added a new configure attribute -- "heading" -- which, if set to zero,
omits the heading REM's containing name, rank, serial number and time
of day.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
My problem is that you need access to v$parameter even if you are NOT using resize.
Subclassing
I cannot write a derived class, that e.g. implements its own _set_sizing() function. What you are suggesting is "delegation". Delegation is not true subclassing, because it does not allow "old code to call new code" as it would be required when I implement my own _set_sizing(). The implementor of a subclass needs more knowledge about the inner workings than the user of an instance (aja oject).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It is quite important to me, that an ordinary user can use DDL::Oracle. Some features may not work, but the operations where access to v$ views is not needed should still work.
Maybe this can be tied to the "view". If the view is user, you get a poor-mans-DDL::Oracle without sizing capabilities and if it is dba you get all the bells and whistles.
With this flexibility there would certainly be no need for me to create a derived class.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I tried to subclass DDL::Oracle, because I wanted to change some behaviour. I
ran across the problem that most global variables were lexically scoped and
thus not accessible from another file.
I am not 100% sure about this, but it seems to me, that global my variables are
problematic, when it comes to subclassing.
It would be helpful to us if you would describe the behaviour you are trying to change. Perhaps there are alternatives.
In Perl terms, DDL::Oracle is strictly OO -- it exports nothing. Its only interface is through the 2 Class methods plus the 5 Object methods. As such, I don't think you can subclass it. But maybe you should explain what *you* mean by "subclass."
You can, of course, operate on the output (e.g., remove the heading (REM's), alter the table/index names, etc. In fact, defrag.pl does this with some of DDL::Oracle's output.
If it is the DDL itself you want to alter, maybe you have found a bug(s). If this is the case, please describe the circumstances.
But mainly, we are interested in what it is you want to change, because there may be others with the same ideas and the changes could be incorporated into the module for all to enjoy.
Dear Maintainers
(1) The _set_sizing() method require access to
v$parameter. Even if I only want to look at
some package code, I need this privilege. I
cannot even get past configure though.
(2) I would like to get PACKAGE and PACKAGE BODY
independently. If I want both I'd rather have
a _get_package_family command.
(3) I found that the 3 lines in a trigger
description sometimes come in a single
line, so the parsing done in _create_trigger
sometimes fails to produce correct syntax. I
can provide a patch.
By subclassing I mean, I wanted to create a
derived class, that has some methods changed
(_create_package, _create_trgger, _get_sizing).
I could not do this because I would have to
access my $dbh, which is not accessible from
outside of DDL::Oracle.
IMHO there should be no global my variables.
They should be either instance variables or
true class variables (I may be wrong though).
In either case you still would not export
anything.
Yes I am removing the REMs the way defrag.pl does
it, even though I'd rather have a "quiet" option.
But this is really not important and it would
require a lot of ifs in the code of DDL::Oracle.
As mentioned before, I think DDL::Oracle is a
wonderful program and it could be the basis for
a lot of useful tools.
BTW: what I am trying to do is to write a
sqlplus replacement (yes, another one), that
is sqlplus compliant and that has a lot of
additional commands (such as PULL PACKAGE -
get the code of a package. This of course
uses DDL::Oracle). The tool will be called
"Senora".
Martin,
Thank you very much for taking the time to submit these comments. I have included 3 of them in the just released Version 1.03. See the Change Log below.
Let's talk about the requirement that the user have access to V$PARAMETER. The 'create' and 'resize' methods for Tables and Indexes include the STORAGE clause entries for INITIAL and NEXT. Some of the Dictionary views hold these values as the number of database blocks. Thus, it is necessary that DDL::Oracle multiply these values by the bytes in the init.ora parameter 'db_block_size'. The only alternative to issuing this query would be to add another config attribute where the user could specify the block size. I am reluctant to do this for 2 reasons. First, I think most users use DDL::Oracle to generate DDL for Tables and Indexes, and that they would prefer not to have to enter this argument. Second, views V$VERSION and V$DATABASE are also accessed -- this is necessary because three Releases of Oracle are supported (7.3, 8.0 and 8i). I also believe (but have no imperical evidence) that access to the V$ views is commonplace. If your DBA's won't give you this access, tell them I said it was OK ;-)
Now, about subclassing. One of the primary benefits of Object Oriented programming is that the users don't have to concern themselves with the inner workings of the Class (module, in Perl's terms). All you have to do is deal with the public interface which, in the case of DDL::Oracle, is pretty simple (IMHO). You wanted to be able to "access my $dbh which is not accessible from outside". But, of course, it IS accessible from outside -- the user program is responsible for obtaining the connection to Oracle, and for passing it into DDL::Oracle for its use. So I'm not sure you have the problem you thought you did.
If you still disagree, add some more ammunition to your argument, and I'll consider it some more.
Cheers.
Richard
----------------
CHANGES (in 1.03)
Rewrote routine for CREATE TRIGGER, which was buggy, farkled and less
than a stellar effort. Added support for SCHEMA and DATABASE triggers.
Separated CREATE PACKAGE BODY from the CREATE PACKAGE function, giving
it its own function. Apologies to users who may have scripts which
rely on the original behavior -- you will need to adapt them if you
upgrade to 1.03 and beyond.
Added a new configure attribute -- "heading" -- which, if set to zero,
omits the heading REM's containing name, rank, serial number and time
of day.
v$parameter
My problem is that you need access to v$parameter even if you are NOT using resize.
Subclassing
I cannot write a derived class, that e.g. implements its own _set_sizing() function. What you are suggesting is "delegation". Delegation is not true subclassing, because it does not allow "old code to call new code" as it would be required when I implement my own _set_sizing(). The implementor of a subclass needs more knowledge about the inner workings than the user of an instance (aja oject).
Martin,
Is there something you'd like to do to _set_sizing other than bypass the query against V$PARAMETER?
Richard
No.
It is quite important to me, that an ordinary user can use DDL::Oracle. Some features may not work, but the operations where access to v$ views is not needed should still work.
Maybe this can be tied to the "view". If the view is user, you get a poor-mans-DDL::Oracle without sizing capabilities and if it is dba you get all the bells and whistles.
With this flexibility there would certainly be no need for me to create a derived class.