After spending a good chunk of my evenings over the last week, here is a summary of the changes/additions I have made (beyond those listed above) in no particular order:
I have replaced your GetTableIndexes implementation with my original one (modified to support ownership) which does the same thing, but with a single hit to the database using joins in the metadata query.
I have renamed the extended properties added to the
CommandSchema object to be consistent with Eric's convention of "
CS_Xxxxx". The
CommandSchema objects returned from the provider will now have the following properties:
- CS_ObjectType (i.e "PACKAGE")
- CS_Status (i.e. "VALID", "INVALID")
- CS_ObjectId (OBJECT_ID of PACKAGE where command resides)
- CS_OverloadNumber (will be -1 if no overload exists, or a number > 0 if overloads are present)
- CS_FullName (will contain the original, "unhacked" up name for the command - more on this below).
I have added support for overloads by reporting the Command.Name property as CUSTOMER.MODIFY[1], CUSTOMER.MODIFY[2], and so on (I thought about using a $ instead of [] to make sure the point was forced syntactically in generated C# code, but in the end decided to go with brackets). What this means is that in order for you to write templates that will handle overloaded Oracle procedures correctly, you'll need to use the CS_FullName extended property value of the CommandSchema object instead of the Name property.
I have added support for a custom configuration file for use with the DLL. This is what it looks like:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<!-- Indicates the schema in which the CODESMITH_EXTENDED_PROPERTIES table should reside.
Comment out this entry to always use current user's schema -->
<!--
<add key="ExtendedPropertiesTableOwner" value="SYSTEM" />
-->
<!-- Indicates whether or not the provider should automatically create the extended properties table.
Setting this to true creates the table in the schema specified by the 'ExtendedPropertiesTableOwner'
value above, or the current user's schema if value isn't present -->
<add key="AutoCreateExtendedPropertiesTable" value="false" />
<!-- Specifies whether to show user owned objects only. -->
<add key="ShowMySchemaOnly" value="true" />
<!-- Specifies whether to allow schema provider to execute procedures that return REF CURSORs to determine
the column schema information. Allowing this can result in a change in the state of the database due to
things like explicit transaction handling in PL/SQL or usage of a sequence's 'nextval' property. -->
<add key="AllowGetCommandResultSchemas" value="false" />
</appSettings>
</configuration>
As you can see, the configuration file contains settings that allow you to control the most critical behavior of the provider. The user can allow the schema provider to go ahead and create the CODESMITH_EXTENDED_PROPERTIES table (which is excluded from the list returned by GetTables, by the way) if it is not present, and yet still control where it gets created and used from. It also allows the user to easily filter the schema objects down to just the ones they own directly. And of course, it allows them to decide whether or not to allow the provider to execute procedures (wrapped in a transactions) to derive the command results.
Also, I cleaned up the existing code a bit. I've gone to using an approach where all database objects are used within using statements, as this automatically invokes the object's Dispose method upon exit. Calling Dispose on the Connections, Commands, and DataReaders does everything that Close does and more. It makes for a more consistent code base, and it's easier to use - the cleanup is done for you automatically.
I have not thoroughly tested all of this new functionality, but I'm comfortable with the results I've seen in my first pass of testing. I will post the source later when I have time. Right now I've got to get some real work done!
Cheers,
Geoff