martinjw / dbschemareader

Read database metadata (from SqlServer/Oracle/MySql/SQLite/PostgreSql/DB2 etc) into one simple model
Microsoft Public License
293 stars 128 forks source link

DB2 Support #112

Open safepage opened 4 years ago

safepage commented 4 years ago

Hello again,

I am now trying to read DB2 schema. I have installed the free DB2 edition and client tools and can connect OK using the generic Factory method... DbProviderFactory factory = DbProviderFactories.GetFactory("IBM.Data.DB2");

The ReaderAdapterFactory has code commented out which would select the Db2ISeriesSchemaReader, so it looks like some work has been done for this.

As it stands the generic ReaderAdapter is selected and no Tables etc are read from the DB schema.

Can you please let me know what is the difference between Adapters and Readers? Would it be fairly easy to create a DB2 adapter from the reader code?

Thanks

martinjw commented 4 years ago

Ok, there are 2 different models here.

  1. Using the underlying DbProvider that's in .net Framework. There is a Db2SchemaReader which is based on SchemaReader which calls the underlying connection.GetSchema() methods and turns the DataTables into real objects.
  2. The newer way replaces the above, partially as .net Core 1-2 didn't have GetSchema(), and in Core 3 it's a no-op. And partially I can do more efficient queries that get more information.

So in the 2nd model there's an adapter per database (picked in the AdapterFactory) which is basically a much simpler version of the XSchemaReader in model 1.

Instead of calling the connection.GetSchema() methods, it calls a set of custom queries which I wrote in ProviderSchemaReaders.Databases. Each query class is based on SqlExecuter, and is usually a single query, for instance to return table names or column details... (In some cases it gets more complex, because of different versions of databases, or just the nature of the metadata).

So almost all the adapters look very simple because the code is something like:

        public override IList<DatabaseTable> Tables(string tableName)
        {
            return new Tables(CommandTimeout, Owner, tableName)
                .Execute(ConnectionAdapter);
        }

The actual logic is in the implementation of the Tables class, which usually just simple sql against the database metadata tables (Information_Schema or for DB2 it's SYSCAT).

So to implement the DB2 calls, you'd have to add a DB2 folder to the Databases, and start adding queries based on SqlExecuter for each type of metadata. In some cases you can just copy the sql from the Db2SchemaReader, which is doing exactly that for Sequences, Table descriptions etc. The standard ones- table names, columns - you may be able to copy what the connection.GetSchema does already, if you can decompile their source code.

Hope this helps