arthurblake / log4jdbc

log4jdbc is a Java JDBC driver that can log SQL and/or JDBC calls (and optionally SQL timing information) for other JDBC drivers using the Simple Logging Facade For Java (SLF4J) logging system.
506 stars 148 forks source link

Ability to extend implementation for example with OraclePreparedStatement #60

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
We need extra  functionality from OracleJdbcDriver.
So, to use for example PreparedStatementSpy  we need create
public class OraclePreparedStatementSpy extends PreparedStatementSpy implements 
PreparedStatement,OraclePreparedStatement
and implement this functionality.
But because in ConnectionSpy constructor for PreparedStatementSpy write 
directly this is not possible.
The  decision is to use factory for spy class which can be configured.
We are going to implement this.
Will we be able to merge this with this branch in future?
If it's possible, could you please give us an advice on this and tell us if 
there are any restrictions?

Original issue reported on code.google.com by MatveevA...@gmail.com on 18 Dec 2012 at 9:13

GoogleCodeExporter commented 9 years ago
What kind of extra functionality do you need?

Original comment by arthur.b...@gmail.com on 20 Dec 2012 at 2:17

GoogleCodeExporter commented 9 years ago
If the extensions needed would work with and be useful to all Oracle drivers 
and usage scenarios maybe RdbmsSpecifics base class itself should have factory 
methods for all the spy classes then OracleRdbmsSpecifics could produce the new 
subclass when the factory method is invoked. 

Original comment by arthur.b...@gmail.com on 20 Dec 2012 at 2:23

GoogleCodeExporter commented 9 years ago
For example:
CallableStatement callableStatement 
=eSession.getDbConnectionManager().acquireConnection().prepareCall(sqlText);    

OracleCallableStatement oracleCallableStatement = 
(OracleCallableStatement)callableStatement;             
oracleCallableStatement.registerOutParameter("s", Types.VARCHAR);
            oracleCallableStatement.execute();

We need to use oracle call because named parameters don't work properly with 
standard jdbc api(oracle 11.2 jdbc driver).
We are going to use the extension to work with  Oracle OCI driver 
specific(OracleCallableStatement.registerIndexTableOutParameter).
We decide not to use OracleRdbmsSpecifics because suppose that extension will 
not be useful to all Oracle drivers. But there are some base class that may be 
used repeatedly.
We already implement this and  Issue 5: Enhancement: Add ability to set 
SpyLogDelegator.
After the functionality will be tested and pass revision, we attach the source. 

Original comment by MatveevA...@gmail.com on 21 Dec 2012 at 8:42

GoogleCodeExporter commented 9 years ago
Most probably they need to change extension between  different versions of 
Oracle OCI driver because some interfaces may change.

Original comment by MatveevA...@gmail.com on 21 Dec 2012 at 8:58

GoogleCodeExporter commented 9 years ago
Oh I thought you needed this to log some extra event information in log4jdbc. 
Instead of casting, can you not just use the Wrapper interface to accomplish 
this task?

See http://docs.oracle.com/javase/6/docs/api/java/sql/Wrapper.html

Original comment by arthur.b...@gmail.com on 21 Dec 2012 at 11:39

GoogleCodeExporter commented 9 years ago
There is no problem to unwrap interfaces. Of course we want to log extra event 
information in log4jdbc. For example we want to log registerOutParameter and 
registerIndexTableOutParameter.   

Original comment by MatveevA...@gmail.com on 21 Dec 2012 at 12:56

GoogleCodeExporter commented 9 years ago
If we will use unwrap we lose the ability to log.

Original comment by MatveevA...@gmail.com on 21 Dec 2012 at 12:59

GoogleCodeExporter commented 9 years ago
I understand - makes sense. Go ahead and implement for yourself and submit the 
patch. If it's done at high quality with good testing, I may merge it later.

Original comment by arthur.b...@gmail.com on 21 Dec 2012 at 1:01

GoogleCodeExporter commented 9 years ago
Ok. I've attached .jar containing our improvements over log4jdbc.

We tried to implement the functionality the same way like it's done in logback.
Now we have a SpySelector interface:

public interface SpySelector {
    public SpyFactory getSpyFactory();
    public SpyLogDelegator getSpyLogDelegator();
}

SpyFactory is responsible for returning Spy entities (ConnectionSpy, 
StatementSpy, ResultSetSpy, etc)
SpyLogDelegator is responsible for returning SpyLogDelegator (Captain Obvious 
here)

Also there is SpyStaticBinder, that selects proper SpySelector (you can also 
implement your own) based on 'log4jdbc.SpySelector' system property. If this 
property is not set, it will select the DefaultSpySelector.
All spy entities are obtained through the SpyFactory (that is returned by 
SpySelector implementation). I also tried to remove all static loggers use from 
log4jdbc.

There are few important points you should pay attention in this implementation
- only Oracle Callable Statement spy is logged. Other Oracle statement classes 
(OraclePreparedStatement/OracleStatement) have stub classes. OracleResult is 
also not loggable.
- due to project needs OracleCallableStatementSpy is realised over several 
ojbdc6 driver versions. It means that those OracleCallableStatement functions 
are not supported by all ojdbc6 versions I worked with don't have an @override 
annotation and throws UnsupportedOperation unchecked exception. Pay attention!

All new created code is covered by the same Apache v2 licence. I hope I didn't 
make any mistakes with licence stuff, but if so, please inform me. Feel free to 
use and modify the code due to your own needs.

Original comment by stas...@gmail.com on 21 Jan 2013 at 6:38

Attachments:

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
I should point that it is experimental version and it was not heavily tested.

As well the idea was to have some basic functionality and the set of extensions.
Extension is the implementation of database-specific spy entities (like it's 
done with Oracle - OracleCallableStatementSpy) and SpySelector/SpyFactories 
implementations.

Original comment by stas...@gmail.com on 21 Jan 2013 at 7:11

GoogleCodeExporter commented 9 years ago
We also use this exstension for AOP 
http://en.wikipedia.org/wiki/Aspect-oriented_programming
for example to monitor transaction context.

Original comment by MatveevA...@gmail.com on 7 Feb 2013 at 6:56

GoogleCodeExporter commented 9 years ago
Hello.
We've performed some changes over SpyFactory and it's inheritors to make 
logging disabling possible.

Now: SpyFactory interfaces now return Connection, Statement, ResultSet instead 
of SpyConnection, SpyStatement, SpyResultSet.
Of course, SpyFactory implementations still can return Spy-entities (every 
Spy-entity implement their entity interface).

But now you can return normal entity instead of Spy one, so logging for this 
entity would be disabled.

You can take a look at this in net.sf.log4jdbc.factory.SpyFactory

Original comment by stas...@gmail.com on 5 Apr 2013 at 9:17

Attachments: