diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..275077f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..275077f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README b/README
deleted file mode 100644
index 734abaf..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-This file was created by IntelliJ IDEA 11.1.1 for binding GitHub repository
\ No newline at end of file
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..275077f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README b/README
deleted file mode 100644
index 734abaf..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-This file was created by IntelliJ IDEA 11.1.1 for binding GitHub repository
\ No newline at end of file
diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml
new file mode 100644
index 0000000..ca90a9b
--- /dev/null
+++ b/Simple-jdbc-statistics.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..275077f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README b/README
deleted file mode 100644
index 734abaf..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-This file was created by IntelliJ IDEA 11.1.1 for binding GitHub repository
\ No newline at end of file
diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml
new file mode 100644
index 0000000..ca90a9b
--- /dev/null
+++ b/Simple-jdbc-statistics.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/h2-1.3.166.jar b/lib/h2-1.3.166.jar
new file mode 100644
index 0000000..4985063
--- /dev/null
+++ b/lib/h2-1.3.166.jar
Binary files differ
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..275077f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README b/README
deleted file mode 100644
index 734abaf..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-This file was created by IntelliJ IDEA 11.1.1 for binding GitHub repository
\ No newline at end of file
diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml
new file mode 100644
index 0000000..ca90a9b
--- /dev/null
+++ b/Simple-jdbc-statistics.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/h2-1.3.166.jar b/lib/h2-1.3.166.jar
new file mode 100644
index 0000000..4985063
--- /dev/null
+++ b/lib/h2-1.3.166.jar
Binary files differ
diff --git a/lib/servlet-api-2.5.jar b/lib/servlet-api-2.5.jar
new file mode 100644
index 0000000..20b5755
--- /dev/null
+++ b/lib/servlet-api-2.5.jar
Binary files differ
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..275077f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README b/README
deleted file mode 100644
index 734abaf..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-This file was created by IntelliJ IDEA 11.1.1 for binding GitHub repository
\ No newline at end of file
diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml
new file mode 100644
index 0000000..ca90a9b
--- /dev/null
+++ b/Simple-jdbc-statistics.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/h2-1.3.166.jar b/lib/h2-1.3.166.jar
new file mode 100644
index 0000000..4985063
--- /dev/null
+++ b/lib/h2-1.3.166.jar
Binary files differ
diff --git a/lib/servlet-api-2.5.jar b/lib/servlet-api-2.5.jar
new file mode 100644
index 0000000..20b5755
--- /dev/null
+++ b/lib/servlet-api-2.5.jar
Binary files differ
diff --git a/lib/slf4j-api-1.6.4.jar b/lib/slf4j-api-1.6.4.jar
new file mode 100644
index 0000000..4d23f41
--- /dev/null
+++ b/lib/slf4j-api-1.6.4.jar
Binary files differ
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..275077f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README b/README
deleted file mode 100644
index 734abaf..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-This file was created by IntelliJ IDEA 11.1.1 for binding GitHub repository
\ No newline at end of file
diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml
new file mode 100644
index 0000000..ca90a9b
--- /dev/null
+++ b/Simple-jdbc-statistics.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/h2-1.3.166.jar b/lib/h2-1.3.166.jar
new file mode 100644
index 0000000..4985063
--- /dev/null
+++ b/lib/h2-1.3.166.jar
Binary files differ
diff --git a/lib/servlet-api-2.5.jar b/lib/servlet-api-2.5.jar
new file mode 100644
index 0000000..20b5755
--- /dev/null
+++ b/lib/servlet-api-2.5.jar
Binary files differ
diff --git a/lib/slf4j-api-1.6.4.jar b/lib/slf4j-api-1.6.4.jar
new file mode 100644
index 0000000..4d23f41
--- /dev/null
+++ b/lib/slf4j-api-1.6.4.jar
Binary files differ
diff --git a/lib/slf4j-simple-1.6.4.jar b/lib/slf4j-simple-1.6.4.jar
new file mode 100644
index 0000000..3d1b8d9
--- /dev/null
+++ b/lib/slf4j-simple-1.6.4.jar
Binary files differ
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..275077f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README b/README
deleted file mode 100644
index 734abaf..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-This file was created by IntelliJ IDEA 11.1.1 for binding GitHub repository
\ No newline at end of file
diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml
new file mode 100644
index 0000000..ca90a9b
--- /dev/null
+++ b/Simple-jdbc-statistics.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/h2-1.3.166.jar b/lib/h2-1.3.166.jar
new file mode 100644
index 0000000..4985063
--- /dev/null
+++ b/lib/h2-1.3.166.jar
Binary files differ
diff --git a/lib/servlet-api-2.5.jar b/lib/servlet-api-2.5.jar
new file mode 100644
index 0000000..20b5755
--- /dev/null
+++ b/lib/servlet-api-2.5.jar
Binary files differ
diff --git a/lib/slf4j-api-1.6.4.jar b/lib/slf4j-api-1.6.4.jar
new file mode 100644
index 0000000..4d23f41
--- /dev/null
+++ b/lib/slf4j-api-1.6.4.jar
Binary files differ
diff --git a/lib/slf4j-simple-1.6.4.jar b/lib/slf4j-simple-1.6.4.jar
new file mode 100644
index 0000000..3d1b8d9
--- /dev/null
+++ b/lib/slf4j-simple-1.6.4.jar
Binary files differ
diff --git a/lib/ssr-0.1.jar b/lib/ssr-0.1.jar
new file mode 100644
index 0000000..65dfcf4
--- /dev/null
+++ b/lib/ssr-0.1.jar
Binary files differ
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..275077f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README b/README
deleted file mode 100644
index 734abaf..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-This file was created by IntelliJ IDEA 11.1.1 for binding GitHub repository
\ No newline at end of file
diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml
new file mode 100644
index 0000000..ca90a9b
--- /dev/null
+++ b/Simple-jdbc-statistics.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/h2-1.3.166.jar b/lib/h2-1.3.166.jar
new file mode 100644
index 0000000..4985063
--- /dev/null
+++ b/lib/h2-1.3.166.jar
Binary files differ
diff --git a/lib/servlet-api-2.5.jar b/lib/servlet-api-2.5.jar
new file mode 100644
index 0000000..20b5755
--- /dev/null
+++ b/lib/servlet-api-2.5.jar
Binary files differ
diff --git a/lib/slf4j-api-1.6.4.jar b/lib/slf4j-api-1.6.4.jar
new file mode 100644
index 0000000..4d23f41
--- /dev/null
+++ b/lib/slf4j-api-1.6.4.jar
Binary files differ
diff --git a/lib/slf4j-simple-1.6.4.jar b/lib/slf4j-simple-1.6.4.jar
new file mode 100644
index 0000000..3d1b8d9
--- /dev/null
+++ b/lib/slf4j-simple-1.6.4.jar
Binary files differ
diff --git a/lib/ssr-0.1.jar b/lib/ssr-0.1.jar
new file mode 100644
index 0000000..65dfcf4
--- /dev/null
+++ b/lib/ssr-0.1.jar
Binary files differ
diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar
new file mode 100644
index 0000000..db63792
--- /dev/null
+++ b/lib/vst-0.4.jar
Binary files differ
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..275077f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README b/README
deleted file mode 100644
index 734abaf..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-This file was created by IntelliJ IDEA 11.1.1 for binding GitHub repository
\ No newline at end of file
diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml
new file mode 100644
index 0000000..ca90a9b
--- /dev/null
+++ b/Simple-jdbc-statistics.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/h2-1.3.166.jar b/lib/h2-1.3.166.jar
new file mode 100644
index 0000000..4985063
--- /dev/null
+++ b/lib/h2-1.3.166.jar
Binary files differ
diff --git a/lib/servlet-api-2.5.jar b/lib/servlet-api-2.5.jar
new file mode 100644
index 0000000..20b5755
--- /dev/null
+++ b/lib/servlet-api-2.5.jar
Binary files differ
diff --git a/lib/slf4j-api-1.6.4.jar b/lib/slf4j-api-1.6.4.jar
new file mode 100644
index 0000000..4d23f41
--- /dev/null
+++ b/lib/slf4j-api-1.6.4.jar
Binary files differ
diff --git a/lib/slf4j-simple-1.6.4.jar b/lib/slf4j-simple-1.6.4.jar
new file mode 100644
index 0000000..3d1b8d9
--- /dev/null
+++ b/lib/slf4j-simple-1.6.4.jar
Binary files differ
diff --git a/lib/ssr-0.1.jar b/lib/ssr-0.1.jar
new file mode 100644
index 0000000..65dfcf4
--- /dev/null
+++ b/lib/ssr-0.1.jar
Binary files differ
diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar
new file mode 100644
index 0000000..db63792
--- /dev/null
+++ b/lib/vst-0.4.jar
Binary files differ
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..ac2dbe1
--- /dev/null
+++ b/readme.md
@@ -0,0 +1 @@
+A simple wrapper around jdbc drivers what will show current jdbc stats of the running queries on a simple web page on port 18080.
\ No newline at end of file
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..275077f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README b/README
deleted file mode 100644
index 734abaf..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-This file was created by IntelliJ IDEA 11.1.1 for binding GitHub repository
\ No newline at end of file
diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml
new file mode 100644
index 0000000..ca90a9b
--- /dev/null
+++ b/Simple-jdbc-statistics.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/h2-1.3.166.jar b/lib/h2-1.3.166.jar
new file mode 100644
index 0000000..4985063
--- /dev/null
+++ b/lib/h2-1.3.166.jar
Binary files differ
diff --git a/lib/servlet-api-2.5.jar b/lib/servlet-api-2.5.jar
new file mode 100644
index 0000000..20b5755
--- /dev/null
+++ b/lib/servlet-api-2.5.jar
Binary files differ
diff --git a/lib/slf4j-api-1.6.4.jar b/lib/slf4j-api-1.6.4.jar
new file mode 100644
index 0000000..4d23f41
--- /dev/null
+++ b/lib/slf4j-api-1.6.4.jar
Binary files differ
diff --git a/lib/slf4j-simple-1.6.4.jar b/lib/slf4j-simple-1.6.4.jar
new file mode 100644
index 0000000..3d1b8d9
--- /dev/null
+++ b/lib/slf4j-simple-1.6.4.jar
Binary files differ
diff --git a/lib/ssr-0.1.jar b/lib/ssr-0.1.jar
new file mode 100644
index 0000000..65dfcf4
--- /dev/null
+++ b/lib/ssr-0.1.jar
Binary files differ
diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar
new file mode 100644
index 0000000..db63792
--- /dev/null
+++ b/lib/vst-0.4.jar
Binary files differ
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..ac2dbe1
--- /dev/null
+++ b/readme.md
@@ -0,0 +1 @@
+A simple wrapper around jdbc drivers what will show current jdbc stats of the running queries on a simple web page on port 18080.
\ No newline at end of file
diff --git a/src/nl/astraeus/jdbc/ConnectionLogger.java b/src/nl/astraeus/jdbc/ConnectionLogger.java
new file mode 100644
index 0000000..c3e243f
--- /dev/null
+++ b/src/nl/astraeus/jdbc/ConnectionLogger.java
@@ -0,0 +1,279 @@
+package nl.astraeus.jdbc;
+
+import java.sql.*;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:12:34 PM
+ */
+public class ConnectionLogger implements Connection {
+ private Connection connection;
+
+ private long milli;
+ private long nano;
+ private String lastSql;
+
+ public ConnectionLogger(Connection connection) {
+ this.connection = connection;
+ this.lastSql = "";
+ }
+
+ private void clearTime() {
+ milli = System.currentTimeMillis();
+ nano = System.nanoTime();
+ }
+
+ private void log(String sql) {
+ long m = System.currentTimeMillis() - milli;
+ long n = System.nanoTime() - nano;
+
+ JdbcLogger.log(QueryType.UNKNOWN, sql, m, n);
+ }
+
+ public void commit() throws SQLException {
+ clearTime();
+
+ connection.commit();
+
+ log("commit");
+ }
+
+ public void rollback() throws SQLException {
+ clearTime();
+
+ connection.rollback();
+
+ log("rollback");
+ }
+
+ public void close() throws SQLException {
+ clearTime();
+
+ connection.close();
+
+ log("close");
+ }
+
+ public PreparedStatement prepareStatement(String sql) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, autoGeneratedKeys);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int columnIndexes[]) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, columnIndexes);
+ }
+
+ public PreparedStatement prepareStatement(String sql, String columnNames[]) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, columnNames);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ public Statement createStatement() throws SQLException {
+ return connection.createStatement();
+ }
+
+ public CallableStatement prepareCall(String sql) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql);
+ }
+
+ public String nativeSQL(String sql) throws SQLException {
+ lastSql = sql;
+ return connection.nativeSQL(sql);
+ }
+
+ public void setAutoCommit(boolean autoCommit) throws SQLException {
+ connection.setAutoCommit(autoCommit);
+ }
+
+ public boolean getAutoCommit() throws SQLException {
+ return connection.getAutoCommit();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return connection.isClosed();
+ }
+
+ public DatabaseMetaData getMetaData() throws SQLException {
+ return connection.getMetaData();
+ }
+
+ public void setReadOnly(boolean readOnly) throws SQLException {
+ connection.setReadOnly(readOnly);
+ }
+
+ public boolean isReadOnly() throws SQLException {
+ return connection.isReadOnly();
+ }
+
+ public void setCatalog(String catalog) throws SQLException {
+ connection.setCatalog(catalog);
+ }
+
+ public String getCatalog() throws SQLException {
+ return connection.getCatalog();
+ }
+
+ public void setTransactionIsolation(int level) throws SQLException {
+ connection.setTransactionIsolation(level);
+ }
+
+ public int getTransactionIsolation() throws SQLException {
+ return connection.getTransactionIsolation();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return connection.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ connection.clearWarnings();
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency);
+ }
+
+ public Map> getTypeMap() throws SQLException {
+ return connection.getTypeMap();
+ }
+
+ public void setTypeMap(Map> map) throws SQLException {
+ connection.setTypeMap(map);
+ }
+
+ public void setHoldability(int holdability) throws SQLException {
+ connection.setHoldability(holdability);
+ }
+
+ public int getHoldability() throws SQLException {
+ return connection.getHoldability();
+ }
+
+ public Savepoint setSavepoint() throws SQLException {
+ return connection.setSavepoint();
+ }
+
+ public Savepoint setSavepoint(String name) throws SQLException {
+ return connection.setSavepoint(name);
+ }
+
+ public void rollback(Savepoint savepoint) throws SQLException {
+ connection.rollback();
+ }
+
+ public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+ connection.releaseSavepoint(savepoint);
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ public Clob createClob() throws SQLException {
+ return connection.createClob();
+ }
+
+ public Blob createBlob() throws SQLException {
+ return connection.createBlob();
+ }
+
+ public NClob createNClob() throws SQLException {
+ return connection.createNClob();
+ }
+
+ public SQLXML createSQLXML() throws SQLException {
+ return connection.createSQLXML();
+ }
+
+ public boolean isValid(int timeout) throws SQLException {
+ return connection.isValid(timeout);
+ }
+
+ public void setClientInfo(String name, String value) throws SQLClientInfoException {
+ connection.setClientInfo(name, value);
+ }
+
+ public void setClientInfo(Properties properties) throws SQLClientInfoException {
+ connection.setClientInfo(properties);
+ }
+
+ public String getClientInfo(String name) throws SQLException {
+ return connection.getClientInfo(name);
+ }
+
+ public Properties getClientInfo() throws SQLException {
+ return connection.getClientInfo();
+ }
+
+ public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
+ return connection.createArrayOf(typeName, elements);
+ }
+
+ public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
+ return connection.createStruct(typeName, attributes);
+ }
+
+ @Override
+ public void setSchema(String schema) throws SQLException {
+ connection.setSchema(schema);
+ }
+
+ @Override
+ public String getSchema() throws SQLException {
+ return connection.getSchema();
+ }
+
+ @Override
+ public void abort(Executor executor) throws SQLException {
+ connection.abort(executor);
+ }
+
+ @Override
+ public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
+ connection.setNetworkTimeout(executor, milliseconds);
+ }
+
+ @Override
+ public int getNetworkTimeout() throws SQLException {
+ return connection.getNetworkTimeout();
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return connection.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return connection.isWrapperFor(iface);
+ }
+}
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..275077f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README b/README
deleted file mode 100644
index 734abaf..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-This file was created by IntelliJ IDEA 11.1.1 for binding GitHub repository
\ No newline at end of file
diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml
new file mode 100644
index 0000000..ca90a9b
--- /dev/null
+++ b/Simple-jdbc-statistics.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/h2-1.3.166.jar b/lib/h2-1.3.166.jar
new file mode 100644
index 0000000..4985063
--- /dev/null
+++ b/lib/h2-1.3.166.jar
Binary files differ
diff --git a/lib/servlet-api-2.5.jar b/lib/servlet-api-2.5.jar
new file mode 100644
index 0000000..20b5755
--- /dev/null
+++ b/lib/servlet-api-2.5.jar
Binary files differ
diff --git a/lib/slf4j-api-1.6.4.jar b/lib/slf4j-api-1.6.4.jar
new file mode 100644
index 0000000..4d23f41
--- /dev/null
+++ b/lib/slf4j-api-1.6.4.jar
Binary files differ
diff --git a/lib/slf4j-simple-1.6.4.jar b/lib/slf4j-simple-1.6.4.jar
new file mode 100644
index 0000000..3d1b8d9
--- /dev/null
+++ b/lib/slf4j-simple-1.6.4.jar
Binary files differ
diff --git a/lib/ssr-0.1.jar b/lib/ssr-0.1.jar
new file mode 100644
index 0000000..65dfcf4
--- /dev/null
+++ b/lib/ssr-0.1.jar
Binary files differ
diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar
new file mode 100644
index 0000000..db63792
--- /dev/null
+++ b/lib/vst-0.4.jar
Binary files differ
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..ac2dbe1
--- /dev/null
+++ b/readme.md
@@ -0,0 +1 @@
+A simple wrapper around jdbc drivers what will show current jdbc stats of the running queries on a simple web page on port 18080.
\ No newline at end of file
diff --git a/src/nl/astraeus/jdbc/ConnectionLogger.java b/src/nl/astraeus/jdbc/ConnectionLogger.java
new file mode 100644
index 0000000..c3e243f
--- /dev/null
+++ b/src/nl/astraeus/jdbc/ConnectionLogger.java
@@ -0,0 +1,279 @@
+package nl.astraeus.jdbc;
+
+import java.sql.*;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:12:34 PM
+ */
+public class ConnectionLogger implements Connection {
+ private Connection connection;
+
+ private long milli;
+ private long nano;
+ private String lastSql;
+
+ public ConnectionLogger(Connection connection) {
+ this.connection = connection;
+ this.lastSql = "";
+ }
+
+ private void clearTime() {
+ milli = System.currentTimeMillis();
+ nano = System.nanoTime();
+ }
+
+ private void log(String sql) {
+ long m = System.currentTimeMillis() - milli;
+ long n = System.nanoTime() - nano;
+
+ JdbcLogger.log(QueryType.UNKNOWN, sql, m, n);
+ }
+
+ public void commit() throws SQLException {
+ clearTime();
+
+ connection.commit();
+
+ log("commit");
+ }
+
+ public void rollback() throws SQLException {
+ clearTime();
+
+ connection.rollback();
+
+ log("rollback");
+ }
+
+ public void close() throws SQLException {
+ clearTime();
+
+ connection.close();
+
+ log("close");
+ }
+
+ public PreparedStatement prepareStatement(String sql) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, autoGeneratedKeys);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int columnIndexes[]) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, columnIndexes);
+ }
+
+ public PreparedStatement prepareStatement(String sql, String columnNames[]) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, columnNames);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ public Statement createStatement() throws SQLException {
+ return connection.createStatement();
+ }
+
+ public CallableStatement prepareCall(String sql) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql);
+ }
+
+ public String nativeSQL(String sql) throws SQLException {
+ lastSql = sql;
+ return connection.nativeSQL(sql);
+ }
+
+ public void setAutoCommit(boolean autoCommit) throws SQLException {
+ connection.setAutoCommit(autoCommit);
+ }
+
+ public boolean getAutoCommit() throws SQLException {
+ return connection.getAutoCommit();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return connection.isClosed();
+ }
+
+ public DatabaseMetaData getMetaData() throws SQLException {
+ return connection.getMetaData();
+ }
+
+ public void setReadOnly(boolean readOnly) throws SQLException {
+ connection.setReadOnly(readOnly);
+ }
+
+ public boolean isReadOnly() throws SQLException {
+ return connection.isReadOnly();
+ }
+
+ public void setCatalog(String catalog) throws SQLException {
+ connection.setCatalog(catalog);
+ }
+
+ public String getCatalog() throws SQLException {
+ return connection.getCatalog();
+ }
+
+ public void setTransactionIsolation(int level) throws SQLException {
+ connection.setTransactionIsolation(level);
+ }
+
+ public int getTransactionIsolation() throws SQLException {
+ return connection.getTransactionIsolation();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return connection.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ connection.clearWarnings();
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency);
+ }
+
+ public Map> getTypeMap() throws SQLException {
+ return connection.getTypeMap();
+ }
+
+ public void setTypeMap(Map> map) throws SQLException {
+ connection.setTypeMap(map);
+ }
+
+ public void setHoldability(int holdability) throws SQLException {
+ connection.setHoldability(holdability);
+ }
+
+ public int getHoldability() throws SQLException {
+ return connection.getHoldability();
+ }
+
+ public Savepoint setSavepoint() throws SQLException {
+ return connection.setSavepoint();
+ }
+
+ public Savepoint setSavepoint(String name) throws SQLException {
+ return connection.setSavepoint(name);
+ }
+
+ public void rollback(Savepoint savepoint) throws SQLException {
+ connection.rollback();
+ }
+
+ public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+ connection.releaseSavepoint(savepoint);
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ public Clob createClob() throws SQLException {
+ return connection.createClob();
+ }
+
+ public Blob createBlob() throws SQLException {
+ return connection.createBlob();
+ }
+
+ public NClob createNClob() throws SQLException {
+ return connection.createNClob();
+ }
+
+ public SQLXML createSQLXML() throws SQLException {
+ return connection.createSQLXML();
+ }
+
+ public boolean isValid(int timeout) throws SQLException {
+ return connection.isValid(timeout);
+ }
+
+ public void setClientInfo(String name, String value) throws SQLClientInfoException {
+ connection.setClientInfo(name, value);
+ }
+
+ public void setClientInfo(Properties properties) throws SQLClientInfoException {
+ connection.setClientInfo(properties);
+ }
+
+ public String getClientInfo(String name) throws SQLException {
+ return connection.getClientInfo(name);
+ }
+
+ public Properties getClientInfo() throws SQLException {
+ return connection.getClientInfo();
+ }
+
+ public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
+ return connection.createArrayOf(typeName, elements);
+ }
+
+ public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
+ return connection.createStruct(typeName, attributes);
+ }
+
+ @Override
+ public void setSchema(String schema) throws SQLException {
+ connection.setSchema(schema);
+ }
+
+ @Override
+ public String getSchema() throws SQLException {
+ return connection.getSchema();
+ }
+
+ @Override
+ public void abort(Executor executor) throws SQLException {
+ connection.abort(executor);
+ }
+
+ @Override
+ public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
+ connection.setNetworkTimeout(executor, milliseconds);
+ }
+
+ @Override
+ public int getNetworkTimeout() throws SQLException {
+ return connection.getNetworkTimeout();
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return connection.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return connection.isWrapperFor(iface);
+ }
+}
diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java
new file mode 100644
index 0000000..8317172
--- /dev/null
+++ b/src/nl/astraeus/jdbc/Driver.java
@@ -0,0 +1,116 @@
+package nl.astraeus.jdbc;
+
+import nl.astraeus.http.SimpleWebServer;
+import nl.astraeus.jdbc.web.JdbcStatisticsServlet;
+import nl.astraeus.jdbc.web.ResourceServlet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.*;
+import java.util.Enumeration;
+import java.util.Properties;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:54:37 PM
+ */
+public class Driver implements java.sql.Driver {
+ private final static Logger log = LoggerFactory.getLogger(Driver.class);
+
+ final private static String URL_PREFIX = "jdbc:stat:";
+
+ private java.sql.Driver driver = null;
+ private String[] drivers = {
+ "org.postgresql.Driver",
+ "oracle.jdbc.driver.OracleDriver",
+ "com.sybase.jdbc2.jdbc.SybDriver",
+ "net.sourceforge.jtds.jdbc.Driver",
+ "com.microsoft.jdbc.sqlserver.SQLServerDriver",
+ "com.microsoft.sqlserver.jdbc.SQLServerDriver",
+ "weblogic.jdbc.sqlserver.SQLServerDriver",
+ "com.informix.jdbc.IfxDriver",
+ "org.apache.derby.jdbc.ClientDriver",
+ "org.apache.derby.jdbc.EmbeddedDriver",
+ "com.mysql.jdbc.Driver",
+ "org.hsqldb.jdbcDriver",
+ "org.h2.Driver" };
+
+ static {
+ log.debug("Loading driver class " + Driver.class.getName());
+
+ try {
+ DriverManager.registerDriver(new Driver());
+ } catch (SQLException e) {
+ log.error("", e);
+ }
+ }
+
+ public Driver() {
+ for (String dr : drivers) {
+ try {
+ Class.forName(dr);
+ } catch (Throwable e) {
+ log.debug("Can't instantiate driver: " + dr, e);
+ }
+ }
+ }
+
+ private java.sql.Driver findDriver(String url) throws SQLException {
+ Enumeration e = DriverManager.getDrivers();
+
+ while (e.hasMoreElements()) {
+ java.sql.Driver d = (java.sql.Driver) e.nextElement();
+
+ if (d.acceptsURL(url)) {
+ return d;
+ }
+ }
+
+ throw new SQLException("Driver not found: " + url);
+ }
+
+ public Connection connect(String url, Properties info) throws SQLException {
+ url = url.substring(URL_PREFIX.length());
+
+ if (driver == null) {
+ driver = findDriver(url);
+ }
+
+ if (driver != null) {
+ SimpleWebServer server = new SimpleWebServer(18080);
+
+ server.addServlet(new JdbcStatisticsServlet(), "/");
+ server.addServlet(new ResourceServlet(), "/resources/*");
+
+ server.start();
+ }
+
+ return new ConnectionLogger(driver.connect(url, info));
+ }
+
+ public boolean acceptsURL(String url) throws SQLException {
+ return (url != null && url.startsWith(URL_PREFIX));
+ }
+
+ public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
+ return driver.getPropertyInfo(url, info);
+ }
+
+ public int getMajorVersion() {
+ return driver.getMajorVersion();
+ }
+
+ public int getMinorVersion() {
+ return driver.getMinorVersion();
+ }
+
+ public boolean jdbcCompliant() {
+ return driver.jdbcCompliant();
+ }
+
+ @Override
+ public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ return driver.getParentLogger();
+ }
+}
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..275077f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README b/README
deleted file mode 100644
index 734abaf..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-This file was created by IntelliJ IDEA 11.1.1 for binding GitHub repository
\ No newline at end of file
diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml
new file mode 100644
index 0000000..ca90a9b
--- /dev/null
+++ b/Simple-jdbc-statistics.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/h2-1.3.166.jar b/lib/h2-1.3.166.jar
new file mode 100644
index 0000000..4985063
--- /dev/null
+++ b/lib/h2-1.3.166.jar
Binary files differ
diff --git a/lib/servlet-api-2.5.jar b/lib/servlet-api-2.5.jar
new file mode 100644
index 0000000..20b5755
--- /dev/null
+++ b/lib/servlet-api-2.5.jar
Binary files differ
diff --git a/lib/slf4j-api-1.6.4.jar b/lib/slf4j-api-1.6.4.jar
new file mode 100644
index 0000000..4d23f41
--- /dev/null
+++ b/lib/slf4j-api-1.6.4.jar
Binary files differ
diff --git a/lib/slf4j-simple-1.6.4.jar b/lib/slf4j-simple-1.6.4.jar
new file mode 100644
index 0000000..3d1b8d9
--- /dev/null
+++ b/lib/slf4j-simple-1.6.4.jar
Binary files differ
diff --git a/lib/ssr-0.1.jar b/lib/ssr-0.1.jar
new file mode 100644
index 0000000..65dfcf4
--- /dev/null
+++ b/lib/ssr-0.1.jar
Binary files differ
diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar
new file mode 100644
index 0000000..db63792
--- /dev/null
+++ b/lib/vst-0.4.jar
Binary files differ
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..ac2dbe1
--- /dev/null
+++ b/readme.md
@@ -0,0 +1 @@
+A simple wrapper around jdbc drivers what will show current jdbc stats of the running queries on a simple web page on port 18080.
\ No newline at end of file
diff --git a/src/nl/astraeus/jdbc/ConnectionLogger.java b/src/nl/astraeus/jdbc/ConnectionLogger.java
new file mode 100644
index 0000000..c3e243f
--- /dev/null
+++ b/src/nl/astraeus/jdbc/ConnectionLogger.java
@@ -0,0 +1,279 @@
+package nl.astraeus.jdbc;
+
+import java.sql.*;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:12:34 PM
+ */
+public class ConnectionLogger implements Connection {
+ private Connection connection;
+
+ private long milli;
+ private long nano;
+ private String lastSql;
+
+ public ConnectionLogger(Connection connection) {
+ this.connection = connection;
+ this.lastSql = "";
+ }
+
+ private void clearTime() {
+ milli = System.currentTimeMillis();
+ nano = System.nanoTime();
+ }
+
+ private void log(String sql) {
+ long m = System.currentTimeMillis() - milli;
+ long n = System.nanoTime() - nano;
+
+ JdbcLogger.log(QueryType.UNKNOWN, sql, m, n);
+ }
+
+ public void commit() throws SQLException {
+ clearTime();
+
+ connection.commit();
+
+ log("commit");
+ }
+
+ public void rollback() throws SQLException {
+ clearTime();
+
+ connection.rollback();
+
+ log("rollback");
+ }
+
+ public void close() throws SQLException {
+ clearTime();
+
+ connection.close();
+
+ log("close");
+ }
+
+ public PreparedStatement prepareStatement(String sql) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, autoGeneratedKeys);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int columnIndexes[]) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, columnIndexes);
+ }
+
+ public PreparedStatement prepareStatement(String sql, String columnNames[]) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, columnNames);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ public Statement createStatement() throws SQLException {
+ return connection.createStatement();
+ }
+
+ public CallableStatement prepareCall(String sql) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql);
+ }
+
+ public String nativeSQL(String sql) throws SQLException {
+ lastSql = sql;
+ return connection.nativeSQL(sql);
+ }
+
+ public void setAutoCommit(boolean autoCommit) throws SQLException {
+ connection.setAutoCommit(autoCommit);
+ }
+
+ public boolean getAutoCommit() throws SQLException {
+ return connection.getAutoCommit();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return connection.isClosed();
+ }
+
+ public DatabaseMetaData getMetaData() throws SQLException {
+ return connection.getMetaData();
+ }
+
+ public void setReadOnly(boolean readOnly) throws SQLException {
+ connection.setReadOnly(readOnly);
+ }
+
+ public boolean isReadOnly() throws SQLException {
+ return connection.isReadOnly();
+ }
+
+ public void setCatalog(String catalog) throws SQLException {
+ connection.setCatalog(catalog);
+ }
+
+ public String getCatalog() throws SQLException {
+ return connection.getCatalog();
+ }
+
+ public void setTransactionIsolation(int level) throws SQLException {
+ connection.setTransactionIsolation(level);
+ }
+
+ public int getTransactionIsolation() throws SQLException {
+ return connection.getTransactionIsolation();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return connection.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ connection.clearWarnings();
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency);
+ }
+
+ public Map> getTypeMap() throws SQLException {
+ return connection.getTypeMap();
+ }
+
+ public void setTypeMap(Map> map) throws SQLException {
+ connection.setTypeMap(map);
+ }
+
+ public void setHoldability(int holdability) throws SQLException {
+ connection.setHoldability(holdability);
+ }
+
+ public int getHoldability() throws SQLException {
+ return connection.getHoldability();
+ }
+
+ public Savepoint setSavepoint() throws SQLException {
+ return connection.setSavepoint();
+ }
+
+ public Savepoint setSavepoint(String name) throws SQLException {
+ return connection.setSavepoint(name);
+ }
+
+ public void rollback(Savepoint savepoint) throws SQLException {
+ connection.rollback();
+ }
+
+ public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+ connection.releaseSavepoint(savepoint);
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ public Clob createClob() throws SQLException {
+ return connection.createClob();
+ }
+
+ public Blob createBlob() throws SQLException {
+ return connection.createBlob();
+ }
+
+ public NClob createNClob() throws SQLException {
+ return connection.createNClob();
+ }
+
+ public SQLXML createSQLXML() throws SQLException {
+ return connection.createSQLXML();
+ }
+
+ public boolean isValid(int timeout) throws SQLException {
+ return connection.isValid(timeout);
+ }
+
+ public void setClientInfo(String name, String value) throws SQLClientInfoException {
+ connection.setClientInfo(name, value);
+ }
+
+ public void setClientInfo(Properties properties) throws SQLClientInfoException {
+ connection.setClientInfo(properties);
+ }
+
+ public String getClientInfo(String name) throws SQLException {
+ return connection.getClientInfo(name);
+ }
+
+ public Properties getClientInfo() throws SQLException {
+ return connection.getClientInfo();
+ }
+
+ public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
+ return connection.createArrayOf(typeName, elements);
+ }
+
+ public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
+ return connection.createStruct(typeName, attributes);
+ }
+
+ @Override
+ public void setSchema(String schema) throws SQLException {
+ connection.setSchema(schema);
+ }
+
+ @Override
+ public String getSchema() throws SQLException {
+ return connection.getSchema();
+ }
+
+ @Override
+ public void abort(Executor executor) throws SQLException {
+ connection.abort(executor);
+ }
+
+ @Override
+ public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
+ connection.setNetworkTimeout(executor, milliseconds);
+ }
+
+ @Override
+ public int getNetworkTimeout() throws SQLException {
+ return connection.getNetworkTimeout();
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return connection.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return connection.isWrapperFor(iface);
+ }
+}
diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java
new file mode 100644
index 0000000..8317172
--- /dev/null
+++ b/src/nl/astraeus/jdbc/Driver.java
@@ -0,0 +1,116 @@
+package nl.astraeus.jdbc;
+
+import nl.astraeus.http.SimpleWebServer;
+import nl.astraeus.jdbc.web.JdbcStatisticsServlet;
+import nl.astraeus.jdbc.web.ResourceServlet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.*;
+import java.util.Enumeration;
+import java.util.Properties;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:54:37 PM
+ */
+public class Driver implements java.sql.Driver {
+ private final static Logger log = LoggerFactory.getLogger(Driver.class);
+
+ final private static String URL_PREFIX = "jdbc:stat:";
+
+ private java.sql.Driver driver = null;
+ private String[] drivers = {
+ "org.postgresql.Driver",
+ "oracle.jdbc.driver.OracleDriver",
+ "com.sybase.jdbc2.jdbc.SybDriver",
+ "net.sourceforge.jtds.jdbc.Driver",
+ "com.microsoft.jdbc.sqlserver.SQLServerDriver",
+ "com.microsoft.sqlserver.jdbc.SQLServerDriver",
+ "weblogic.jdbc.sqlserver.SQLServerDriver",
+ "com.informix.jdbc.IfxDriver",
+ "org.apache.derby.jdbc.ClientDriver",
+ "org.apache.derby.jdbc.EmbeddedDriver",
+ "com.mysql.jdbc.Driver",
+ "org.hsqldb.jdbcDriver",
+ "org.h2.Driver" };
+
+ static {
+ log.debug("Loading driver class " + Driver.class.getName());
+
+ try {
+ DriverManager.registerDriver(new Driver());
+ } catch (SQLException e) {
+ log.error("", e);
+ }
+ }
+
+ public Driver() {
+ for (String dr : drivers) {
+ try {
+ Class.forName(dr);
+ } catch (Throwable e) {
+ log.debug("Can't instantiate driver: " + dr, e);
+ }
+ }
+ }
+
+ private java.sql.Driver findDriver(String url) throws SQLException {
+ Enumeration e = DriverManager.getDrivers();
+
+ while (e.hasMoreElements()) {
+ java.sql.Driver d = (java.sql.Driver) e.nextElement();
+
+ if (d.acceptsURL(url)) {
+ return d;
+ }
+ }
+
+ throw new SQLException("Driver not found: " + url);
+ }
+
+ public Connection connect(String url, Properties info) throws SQLException {
+ url = url.substring(URL_PREFIX.length());
+
+ if (driver == null) {
+ driver = findDriver(url);
+ }
+
+ if (driver != null) {
+ SimpleWebServer server = new SimpleWebServer(18080);
+
+ server.addServlet(new JdbcStatisticsServlet(), "/");
+ server.addServlet(new ResourceServlet(), "/resources/*");
+
+ server.start();
+ }
+
+ return new ConnectionLogger(driver.connect(url, info));
+ }
+
+ public boolean acceptsURL(String url) throws SQLException {
+ return (url != null && url.startsWith(URL_PREFIX));
+ }
+
+ public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
+ return driver.getPropertyInfo(url, info);
+ }
+
+ public int getMajorVersion() {
+ return driver.getMajorVersion();
+ }
+
+ public int getMinorVersion() {
+ return driver.getMinorVersion();
+ }
+
+ public boolean jdbcCompliant() {
+ return driver.jdbcCompliant();
+ }
+
+ @Override
+ public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ return driver.getParentLogger();
+ }
+}
diff --git a/src/nl/astraeus/jdbc/JdbcLogger.java b/src/nl/astraeus/jdbc/JdbcLogger.java
new file mode 100644
index 0000000..f4bc125
--- /dev/null
+++ b/src/nl/astraeus/jdbc/JdbcLogger.java
@@ -0,0 +1,113 @@
+package nl.astraeus.jdbc;
+
+import nl.astraeus.jdbc.util.Util;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * User: riennentjes
+ * Date: Jul 12, 2008
+ * Time: 9:15:21 AM
+ */
+public class JdbcLogger {
+ private final static Logger logger = LoggerFactory.getLogger(JdbcLogger.class);
+
+ private final static JdbcLogger instance = new JdbcLogger();
+
+ public static JdbcLogger get() {
+ return instance;
+ }
+
+ public final static class LogEntry {
+ public QueryType type;
+ public String sql;
+ public long milli;
+ public long nano;
+ public int count;
+ public int hash;
+
+ public LogEntry(int hash, QueryType type, String sql, long milli, long nano) {
+ this.hash = hash;
+ this.type = type;
+ this.sql = sql;
+ this.milli = milli;
+ this.nano = nano;
+ this.count = 1;
+ }
+
+ public void addCount(long milli, long nano) {
+ synchronized (this) {
+ count++;
+ this.milli += milli;
+ this.nano += nano;
+ }
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public String getMilli() {
+ return Util.formatNano(milli*1000000/count);
+ }
+
+ public String getNano() {
+ return Util.formatNano(nano/count);
+ }
+
+ public String getTotal() {
+ return Util.formatNano(nano);
+ }
+
+ public String getSql() {
+ return sql;
+ }
+ }
+
+ private Map queries;
+
+ public JdbcLogger() {
+ queries = new ConcurrentHashMap();
+ }
+
+ public void logEntry(QueryType type, String sql, long milli, long nano) {
+ int hash = sql.hashCode();
+ LogEntry entry = queries.get(hash);
+
+ if (entry == null) {
+ entry = new LogEntry(hash, type, sql, milli, nano);
+ queries.put(hash, entry);
+ } else {
+ entry.addCount(milli, nano);
+ }
+
+ if (queries.size() > 1000) {
+ List toRemove = new LinkedList();
+ List values = new LinkedList(queries.values());
+
+ Collections.sort(values, new Comparator() {
+ @Override
+ public int compare(LogEntry o1, LogEntry o2) {
+ return o1.count - o2.count;
+ }
+ });
+
+ while (queries.size() > 900) {
+ queries.remove(values.remove(0).hash);
+
+ }
+ }
+ }
+
+ public static void log(QueryType type, String sql, long milli, long nano) {
+ instance.logEntry(type, sql, milli, nano);
+ }
+
+ public Collection getEntries() {
+ return queries.values();
+ }
+
+}
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..275077f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README b/README
deleted file mode 100644
index 734abaf..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-This file was created by IntelliJ IDEA 11.1.1 for binding GitHub repository
\ No newline at end of file
diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml
new file mode 100644
index 0000000..ca90a9b
--- /dev/null
+++ b/Simple-jdbc-statistics.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/h2-1.3.166.jar b/lib/h2-1.3.166.jar
new file mode 100644
index 0000000..4985063
--- /dev/null
+++ b/lib/h2-1.3.166.jar
Binary files differ
diff --git a/lib/servlet-api-2.5.jar b/lib/servlet-api-2.5.jar
new file mode 100644
index 0000000..20b5755
--- /dev/null
+++ b/lib/servlet-api-2.5.jar
Binary files differ
diff --git a/lib/slf4j-api-1.6.4.jar b/lib/slf4j-api-1.6.4.jar
new file mode 100644
index 0000000..4d23f41
--- /dev/null
+++ b/lib/slf4j-api-1.6.4.jar
Binary files differ
diff --git a/lib/slf4j-simple-1.6.4.jar b/lib/slf4j-simple-1.6.4.jar
new file mode 100644
index 0000000..3d1b8d9
--- /dev/null
+++ b/lib/slf4j-simple-1.6.4.jar
Binary files differ
diff --git a/lib/ssr-0.1.jar b/lib/ssr-0.1.jar
new file mode 100644
index 0000000..65dfcf4
--- /dev/null
+++ b/lib/ssr-0.1.jar
Binary files differ
diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar
new file mode 100644
index 0000000..db63792
--- /dev/null
+++ b/lib/vst-0.4.jar
Binary files differ
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..ac2dbe1
--- /dev/null
+++ b/readme.md
@@ -0,0 +1 @@
+A simple wrapper around jdbc drivers what will show current jdbc stats of the running queries on a simple web page on port 18080.
\ No newline at end of file
diff --git a/src/nl/astraeus/jdbc/ConnectionLogger.java b/src/nl/astraeus/jdbc/ConnectionLogger.java
new file mode 100644
index 0000000..c3e243f
--- /dev/null
+++ b/src/nl/astraeus/jdbc/ConnectionLogger.java
@@ -0,0 +1,279 @@
+package nl.astraeus.jdbc;
+
+import java.sql.*;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:12:34 PM
+ */
+public class ConnectionLogger implements Connection {
+ private Connection connection;
+
+ private long milli;
+ private long nano;
+ private String lastSql;
+
+ public ConnectionLogger(Connection connection) {
+ this.connection = connection;
+ this.lastSql = "";
+ }
+
+ private void clearTime() {
+ milli = System.currentTimeMillis();
+ nano = System.nanoTime();
+ }
+
+ private void log(String sql) {
+ long m = System.currentTimeMillis() - milli;
+ long n = System.nanoTime() - nano;
+
+ JdbcLogger.log(QueryType.UNKNOWN, sql, m, n);
+ }
+
+ public void commit() throws SQLException {
+ clearTime();
+
+ connection.commit();
+
+ log("commit");
+ }
+
+ public void rollback() throws SQLException {
+ clearTime();
+
+ connection.rollback();
+
+ log("rollback");
+ }
+
+ public void close() throws SQLException {
+ clearTime();
+
+ connection.close();
+
+ log("close");
+ }
+
+ public PreparedStatement prepareStatement(String sql) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, autoGeneratedKeys);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int columnIndexes[]) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, columnIndexes);
+ }
+
+ public PreparedStatement prepareStatement(String sql, String columnNames[]) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, columnNames);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ public Statement createStatement() throws SQLException {
+ return connection.createStatement();
+ }
+
+ public CallableStatement prepareCall(String sql) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql);
+ }
+
+ public String nativeSQL(String sql) throws SQLException {
+ lastSql = sql;
+ return connection.nativeSQL(sql);
+ }
+
+ public void setAutoCommit(boolean autoCommit) throws SQLException {
+ connection.setAutoCommit(autoCommit);
+ }
+
+ public boolean getAutoCommit() throws SQLException {
+ return connection.getAutoCommit();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return connection.isClosed();
+ }
+
+ public DatabaseMetaData getMetaData() throws SQLException {
+ return connection.getMetaData();
+ }
+
+ public void setReadOnly(boolean readOnly) throws SQLException {
+ connection.setReadOnly(readOnly);
+ }
+
+ public boolean isReadOnly() throws SQLException {
+ return connection.isReadOnly();
+ }
+
+ public void setCatalog(String catalog) throws SQLException {
+ connection.setCatalog(catalog);
+ }
+
+ public String getCatalog() throws SQLException {
+ return connection.getCatalog();
+ }
+
+ public void setTransactionIsolation(int level) throws SQLException {
+ connection.setTransactionIsolation(level);
+ }
+
+ public int getTransactionIsolation() throws SQLException {
+ return connection.getTransactionIsolation();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return connection.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ connection.clearWarnings();
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency);
+ }
+
+ public Map> getTypeMap() throws SQLException {
+ return connection.getTypeMap();
+ }
+
+ public void setTypeMap(Map> map) throws SQLException {
+ connection.setTypeMap(map);
+ }
+
+ public void setHoldability(int holdability) throws SQLException {
+ connection.setHoldability(holdability);
+ }
+
+ public int getHoldability() throws SQLException {
+ return connection.getHoldability();
+ }
+
+ public Savepoint setSavepoint() throws SQLException {
+ return connection.setSavepoint();
+ }
+
+ public Savepoint setSavepoint(String name) throws SQLException {
+ return connection.setSavepoint(name);
+ }
+
+ public void rollback(Savepoint savepoint) throws SQLException {
+ connection.rollback();
+ }
+
+ public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+ connection.releaseSavepoint(savepoint);
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ public Clob createClob() throws SQLException {
+ return connection.createClob();
+ }
+
+ public Blob createBlob() throws SQLException {
+ return connection.createBlob();
+ }
+
+ public NClob createNClob() throws SQLException {
+ return connection.createNClob();
+ }
+
+ public SQLXML createSQLXML() throws SQLException {
+ return connection.createSQLXML();
+ }
+
+ public boolean isValid(int timeout) throws SQLException {
+ return connection.isValid(timeout);
+ }
+
+ public void setClientInfo(String name, String value) throws SQLClientInfoException {
+ connection.setClientInfo(name, value);
+ }
+
+ public void setClientInfo(Properties properties) throws SQLClientInfoException {
+ connection.setClientInfo(properties);
+ }
+
+ public String getClientInfo(String name) throws SQLException {
+ return connection.getClientInfo(name);
+ }
+
+ public Properties getClientInfo() throws SQLException {
+ return connection.getClientInfo();
+ }
+
+ public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
+ return connection.createArrayOf(typeName, elements);
+ }
+
+ public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
+ return connection.createStruct(typeName, attributes);
+ }
+
+ @Override
+ public void setSchema(String schema) throws SQLException {
+ connection.setSchema(schema);
+ }
+
+ @Override
+ public String getSchema() throws SQLException {
+ return connection.getSchema();
+ }
+
+ @Override
+ public void abort(Executor executor) throws SQLException {
+ connection.abort(executor);
+ }
+
+ @Override
+ public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
+ connection.setNetworkTimeout(executor, milliseconds);
+ }
+
+ @Override
+ public int getNetworkTimeout() throws SQLException {
+ return connection.getNetworkTimeout();
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return connection.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return connection.isWrapperFor(iface);
+ }
+}
diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java
new file mode 100644
index 0000000..8317172
--- /dev/null
+++ b/src/nl/astraeus/jdbc/Driver.java
@@ -0,0 +1,116 @@
+package nl.astraeus.jdbc;
+
+import nl.astraeus.http.SimpleWebServer;
+import nl.astraeus.jdbc.web.JdbcStatisticsServlet;
+import nl.astraeus.jdbc.web.ResourceServlet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.*;
+import java.util.Enumeration;
+import java.util.Properties;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:54:37 PM
+ */
+public class Driver implements java.sql.Driver {
+ private final static Logger log = LoggerFactory.getLogger(Driver.class);
+
+ final private static String URL_PREFIX = "jdbc:stat:";
+
+ private java.sql.Driver driver = null;
+ private String[] drivers = {
+ "org.postgresql.Driver",
+ "oracle.jdbc.driver.OracleDriver",
+ "com.sybase.jdbc2.jdbc.SybDriver",
+ "net.sourceforge.jtds.jdbc.Driver",
+ "com.microsoft.jdbc.sqlserver.SQLServerDriver",
+ "com.microsoft.sqlserver.jdbc.SQLServerDriver",
+ "weblogic.jdbc.sqlserver.SQLServerDriver",
+ "com.informix.jdbc.IfxDriver",
+ "org.apache.derby.jdbc.ClientDriver",
+ "org.apache.derby.jdbc.EmbeddedDriver",
+ "com.mysql.jdbc.Driver",
+ "org.hsqldb.jdbcDriver",
+ "org.h2.Driver" };
+
+ static {
+ log.debug("Loading driver class " + Driver.class.getName());
+
+ try {
+ DriverManager.registerDriver(new Driver());
+ } catch (SQLException e) {
+ log.error("", e);
+ }
+ }
+
+ public Driver() {
+ for (String dr : drivers) {
+ try {
+ Class.forName(dr);
+ } catch (Throwable e) {
+ log.debug("Can't instantiate driver: " + dr, e);
+ }
+ }
+ }
+
+ private java.sql.Driver findDriver(String url) throws SQLException {
+ Enumeration e = DriverManager.getDrivers();
+
+ while (e.hasMoreElements()) {
+ java.sql.Driver d = (java.sql.Driver) e.nextElement();
+
+ if (d.acceptsURL(url)) {
+ return d;
+ }
+ }
+
+ throw new SQLException("Driver not found: " + url);
+ }
+
+ public Connection connect(String url, Properties info) throws SQLException {
+ url = url.substring(URL_PREFIX.length());
+
+ if (driver == null) {
+ driver = findDriver(url);
+ }
+
+ if (driver != null) {
+ SimpleWebServer server = new SimpleWebServer(18080);
+
+ server.addServlet(new JdbcStatisticsServlet(), "/");
+ server.addServlet(new ResourceServlet(), "/resources/*");
+
+ server.start();
+ }
+
+ return new ConnectionLogger(driver.connect(url, info));
+ }
+
+ public boolean acceptsURL(String url) throws SQLException {
+ return (url != null && url.startsWith(URL_PREFIX));
+ }
+
+ public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
+ return driver.getPropertyInfo(url, info);
+ }
+
+ public int getMajorVersion() {
+ return driver.getMajorVersion();
+ }
+
+ public int getMinorVersion() {
+ return driver.getMinorVersion();
+ }
+
+ public boolean jdbcCompliant() {
+ return driver.jdbcCompliant();
+ }
+
+ @Override
+ public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ return driver.getParentLogger();
+ }
+}
diff --git a/src/nl/astraeus/jdbc/JdbcLogger.java b/src/nl/astraeus/jdbc/JdbcLogger.java
new file mode 100644
index 0000000..f4bc125
--- /dev/null
+++ b/src/nl/astraeus/jdbc/JdbcLogger.java
@@ -0,0 +1,113 @@
+package nl.astraeus.jdbc;
+
+import nl.astraeus.jdbc.util.Util;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * User: riennentjes
+ * Date: Jul 12, 2008
+ * Time: 9:15:21 AM
+ */
+public class JdbcLogger {
+ private final static Logger logger = LoggerFactory.getLogger(JdbcLogger.class);
+
+ private final static JdbcLogger instance = new JdbcLogger();
+
+ public static JdbcLogger get() {
+ return instance;
+ }
+
+ public final static class LogEntry {
+ public QueryType type;
+ public String sql;
+ public long milli;
+ public long nano;
+ public int count;
+ public int hash;
+
+ public LogEntry(int hash, QueryType type, String sql, long milli, long nano) {
+ this.hash = hash;
+ this.type = type;
+ this.sql = sql;
+ this.milli = milli;
+ this.nano = nano;
+ this.count = 1;
+ }
+
+ public void addCount(long milli, long nano) {
+ synchronized (this) {
+ count++;
+ this.milli += milli;
+ this.nano += nano;
+ }
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public String getMilli() {
+ return Util.formatNano(milli*1000000/count);
+ }
+
+ public String getNano() {
+ return Util.formatNano(nano/count);
+ }
+
+ public String getTotal() {
+ return Util.formatNano(nano);
+ }
+
+ public String getSql() {
+ return sql;
+ }
+ }
+
+ private Map queries;
+
+ public JdbcLogger() {
+ queries = new ConcurrentHashMap();
+ }
+
+ public void logEntry(QueryType type, String sql, long milli, long nano) {
+ int hash = sql.hashCode();
+ LogEntry entry = queries.get(hash);
+
+ if (entry == null) {
+ entry = new LogEntry(hash, type, sql, milli, nano);
+ queries.put(hash, entry);
+ } else {
+ entry.addCount(milli, nano);
+ }
+
+ if (queries.size() > 1000) {
+ List toRemove = new LinkedList();
+ List values = new LinkedList(queries.values());
+
+ Collections.sort(values, new Comparator() {
+ @Override
+ public int compare(LogEntry o1, LogEntry o2) {
+ return o1.count - o2.count;
+ }
+ });
+
+ while (queries.size() > 900) {
+ queries.remove(values.remove(0).hash);
+
+ }
+ }
+ }
+
+ public static void log(QueryType type, String sql, long milli, long nano) {
+ instance.logEntry(type, sql, milli, nano);
+ }
+
+ public Collection getEntries() {
+ return queries.values();
+ }
+
+}
diff --git a/src/nl/astraeus/jdbc/PreparedStatementLogger.java b/src/nl/astraeus/jdbc/PreparedStatementLogger.java
new file mode 100644
index 0000000..98aefc7
--- /dev/null
+++ b/src/nl/astraeus/jdbc/PreparedStatementLogger.java
@@ -0,0 +1,577 @@
+package nl.astraeus.jdbc;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.*;
+import java.util.Calendar;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 7:47:57 PM
+ */
+public class PreparedStatementLogger implements PreparedStatement {
+ private final static Logger log = LoggerFactory.getLogger(PreparedStatementLogger.class);
+
+ private PreparedStatement statement;
+
+ private String sql;
+ private QueryType type;
+ private long milli;
+ private long nano;
+
+ //private ArrayList parameters;
+
+ public PreparedStatementLogger(PreparedStatement statement) {
+ this.statement = statement;
+ this.sql = "";
+ this.type = QueryType.UNKNOWN;
+ }
+
+ private void clearTime() {
+ milli = System.currentTimeMillis();
+ nano = System.nanoTime();
+ }
+
+ private void log(QueryType type, String sql) {
+ long m = System.currentTimeMillis() - milli;
+ long n = System.nanoTime() - nano;
+
+ JdbcLogger.log(type, sql, m, n);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, resultSetType, resultSetConcurrency);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, autoGeneratedKeys);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int[] columnIndexes) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, columnIndexes);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, String[] columnNames) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, columnNames);
+ }
+
+ public boolean execute() throws SQLException {
+ clearTime();
+
+ boolean result = statement.execute();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public ResultSet executeQuery() throws SQLException {
+ clearTime();
+
+ ResultSet result = statement.executeQuery();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate() throws SQLException {
+ clearTime();
+
+ int result = statement.executeUpdate();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public ResultSet executeQuery(String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ ResultSet result = statement.executeQuery(sql);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, autoGeneratedKeys);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, int columnIndexes[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, columnIndexes);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, String columnNames[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, columnNames);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, autoGeneratedKeys);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, int columnIndexes[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, columnIndexes);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, String columnNames[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, columnNames);
+
+ log(type, sql);
+
+ return result;
+ }
+
+
+ public void setNull(int parameterIndex, int sqlType) throws SQLException {
+ statement.setNull(parameterIndex, sqlType);
+ }
+
+ public void setBoolean(int parameterIndex, boolean x) throws SQLException {
+ statement.setBoolean(parameterIndex, x);
+ }
+
+ public void setByte(int parameterIndex, byte x) throws SQLException {
+ statement.setByte(parameterIndex, x);
+ }
+
+ public void setShort(int parameterIndex, short x) throws SQLException {
+ statement.setShort(parameterIndex, x);
+ }
+
+ public void setInt(int parameterIndex, int x) throws SQLException {
+ statement.setInt(parameterIndex, x);
+ }
+
+ public void setLong(int parameterIndex, long x) throws SQLException {
+ statement.setLong(parameterIndex, x);
+ }
+
+ public void setFloat(int parameterIndex, float x) throws SQLException {
+ statement.setFloat(parameterIndex, x);
+ }
+
+ public void setDouble(int parameterIndex, double x) throws SQLException {
+ statement.setDouble(parameterIndex, x);
+ }
+
+ public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
+ statement.setBigDecimal(parameterIndex, x);
+ }
+
+ public void setString(int parameterIndex, String x) throws SQLException {
+ statement.setString(parameterIndex, x);
+ }
+
+ public void setBytes(int parameterIndex, byte x[]) throws SQLException {
+ statement.setBytes(parameterIndex, x);
+ }
+
+ public void setDate(int parameterIndex, Date x) throws SQLException {
+ statement.setDate(parameterIndex, x);
+ }
+
+ public void setTime(int parameterIndex, Time x) throws SQLException {
+ statement.setTime(parameterIndex, x);
+ }
+
+ public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
+ statement.setTimestamp(parameterIndex, x);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x, length);
+ }
+
+ public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setUnicodeStream(parameterIndex, x, length);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x, length);
+ }
+
+ public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
+ statement.setObject(parameterIndex, x, targetSqlType);
+ }
+
+ public void setObject(int parameterIndex, Object x) throws SQLException {
+ statement.setObject(parameterIndex, x);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ public void setRef(int parameterIndex, Ref x) throws SQLException {
+ statement.setRef(parameterIndex, x);
+ }
+
+ public void setBlob(int parameterIndex, Blob x) throws SQLException {
+ statement.setBlob(parameterIndex, x);
+ }
+
+ public void setClob(int parameterIndex, Clob x) throws SQLException {
+ statement.setClob(parameterIndex, x);
+ }
+
+ public void setArray(int parameterIndex, Array x) throws SQLException {
+ statement.setArray(parameterIndex, x);
+ }
+
+ public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
+ statement.setDate(parameterIndex, x, cal);
+ }
+
+ public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
+ statement.setTime(parameterIndex, x, cal);
+ }
+
+ public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
+ statement.setTimestamp(parameterIndex, x, cal);
+ }
+
+ public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
+ statement.setNull(parameterIndex, sqlType, typeName);
+ }
+
+ public void setURL(int parameterIndex, URL x) throws SQLException {
+ statement.setURL(parameterIndex, x);
+ }
+
+ public void setRowId(int parameterIndex, RowId x) throws SQLException {
+ statement.setRowId(parameterIndex, x);
+ }
+
+ public void setNString(int parameterIndex, String value) throws SQLException {
+ statement.setNString(parameterIndex, value);
+ }
+
+ public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
+ statement.setNCharacterStream(parameterIndex, value, length);
+ }
+
+ public void setNClob(int parameterIndex, NClob value) throws SQLException {
+ statement.setNClob(parameterIndex, value);
+ }
+
+ public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setClob(parameterIndex, reader, length);
+ }
+
+ public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
+ statement.setBlob(parameterIndex, inputStream, length);
+ }
+
+ public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setNClob(parameterIndex, reader, length);
+ }
+
+ public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
+ statement.setSQLXML(parameterIndex, xmlObject);
+ }
+
+ public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException {
+ statement.setObject(parameterIndex, x, targetSqlType, scaleOrLength);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x, length);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x, length);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader);
+ }
+
+ public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
+ statement.setNCharacterStream(parameterIndex, value);
+ }
+
+ public void setClob(int parameterIndex, Reader reader) throws SQLException {
+ statement.setClob(parameterIndex, reader);
+ }
+
+ public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
+ statement.setBlob(parameterIndex, inputStream);
+ }
+
+ public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+ statement.setNClob(parameterIndex, reader);
+ }
+
+
+ public void close() throws SQLException {
+ sql = "";
+ type = QueryType.UNKNOWN;
+ milli = 0;
+ nano = 0;
+
+ statement.close();
+ }
+
+ public ResultSetMetaData getMetaData() throws SQLException {
+ return statement.getMetaData();
+ }
+
+ public void clearParameters() throws SQLException {
+ statement.clearParameters();
+ }
+
+ public ParameterMetaData getParameterMetaData() throws SQLException {
+ return statement.getParameterMetaData();
+ }
+
+ public void addBatch() throws SQLException {
+ statement.addBatch();
+ }
+
+ public int getMaxFieldSize() throws SQLException {
+ return statement.getMaxFieldSize();
+ }
+
+ public void setMaxFieldSize(int max) throws SQLException {
+ statement.setMaxFieldSize(max);
+ }
+
+ public int getMaxRows() throws SQLException {
+ return statement.getMaxRows();
+ }
+
+ public void setMaxRows(int max) throws SQLException {
+ statement.setMaxRows(max);
+ }
+
+ public void setEscapeProcessing(boolean enable) throws SQLException {
+ statement.setEscapeProcessing(enable);
+ }
+
+ public int getQueryTimeout() throws SQLException {
+ return statement.getQueryTimeout();
+ }
+
+ public void setQueryTimeout(int seconds) throws SQLException {
+ statement.setQueryTimeout(seconds);
+ }
+
+ public void cancel() throws SQLException {
+ statement.cancel();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return statement.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ statement.clearWarnings();
+ }
+
+ public void setCursorName(String name) throws SQLException {
+ statement.setCursorName(name);
+ }
+
+ public boolean execute(String sql) throws SQLException {
+ return statement.execute(sql);
+ }
+
+ public ResultSet getResultSet() throws SQLException {
+ return statement.getResultSet();
+ }
+
+ public int getUpdateCount() throws SQLException {
+ return statement.getUpdateCount();
+ }
+
+ public boolean getMoreResults() throws SQLException {
+ return statement.getMoreResults();
+ }
+
+ public void setFetchDirection(int direction) throws SQLException {
+ statement.setFetchDirection(direction);
+ }
+
+ public int getFetchDirection() throws SQLException {
+ return statement.getFetchDirection();
+ }
+
+ public void setFetchSize(int rows) throws SQLException {
+ statement.setFetchSize(rows);
+ }
+
+ public int getFetchSize() throws SQLException {
+ return statement.getFetchSize();
+ }
+
+ public int getResultSetConcurrency() throws SQLException {
+ return statement.getResultSetConcurrency();
+ }
+
+ public int getResultSetType() throws SQLException {
+ return statement.getResultSetType();
+ }
+
+ public void addBatch(String sql) throws SQLException {
+ statement.addBatch(sql);
+ }
+
+ public void clearBatch() throws SQLException {
+ statement.clearBatch();
+ }
+
+ public int[] executeBatch() throws SQLException {
+ return statement.executeBatch();
+ }
+
+ public Connection getConnection() throws SQLException {
+ return statement.getConnection();
+ }
+
+ public boolean getMoreResults(int current) throws SQLException {
+ return statement.getMoreResults(current);
+ }
+
+ public ResultSet getGeneratedKeys() throws SQLException {
+ return statement.getGeneratedKeys();
+ }
+
+ public int getResultSetHoldability() throws SQLException {
+ return statement.getResultSetHoldability();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return statement.isClosed();
+ }
+
+ public void setPoolable(boolean poolable) throws SQLException {
+ statement.setPoolable(poolable);
+ }
+
+ public boolean isPoolable() throws SQLException {
+ return statement.isPoolable();
+ }
+
+ @Override
+ public void closeOnCompletion() throws SQLException {
+ statement.closeOnCompletion();;
+ }
+
+ @Override
+ public boolean isCloseOnCompletion() throws SQLException {
+ return statement.isCloseOnCompletion();
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return statement.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return statement.isWrapperFor(iface);
+ }
+}
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..275077f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README b/README
deleted file mode 100644
index 734abaf..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-This file was created by IntelliJ IDEA 11.1.1 for binding GitHub repository
\ No newline at end of file
diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml
new file mode 100644
index 0000000..ca90a9b
--- /dev/null
+++ b/Simple-jdbc-statistics.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/h2-1.3.166.jar b/lib/h2-1.3.166.jar
new file mode 100644
index 0000000..4985063
--- /dev/null
+++ b/lib/h2-1.3.166.jar
Binary files differ
diff --git a/lib/servlet-api-2.5.jar b/lib/servlet-api-2.5.jar
new file mode 100644
index 0000000..20b5755
--- /dev/null
+++ b/lib/servlet-api-2.5.jar
Binary files differ
diff --git a/lib/slf4j-api-1.6.4.jar b/lib/slf4j-api-1.6.4.jar
new file mode 100644
index 0000000..4d23f41
--- /dev/null
+++ b/lib/slf4j-api-1.6.4.jar
Binary files differ
diff --git a/lib/slf4j-simple-1.6.4.jar b/lib/slf4j-simple-1.6.4.jar
new file mode 100644
index 0000000..3d1b8d9
--- /dev/null
+++ b/lib/slf4j-simple-1.6.4.jar
Binary files differ
diff --git a/lib/ssr-0.1.jar b/lib/ssr-0.1.jar
new file mode 100644
index 0000000..65dfcf4
--- /dev/null
+++ b/lib/ssr-0.1.jar
Binary files differ
diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar
new file mode 100644
index 0000000..db63792
--- /dev/null
+++ b/lib/vst-0.4.jar
Binary files differ
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..ac2dbe1
--- /dev/null
+++ b/readme.md
@@ -0,0 +1 @@
+A simple wrapper around jdbc drivers what will show current jdbc stats of the running queries on a simple web page on port 18080.
\ No newline at end of file
diff --git a/src/nl/astraeus/jdbc/ConnectionLogger.java b/src/nl/astraeus/jdbc/ConnectionLogger.java
new file mode 100644
index 0000000..c3e243f
--- /dev/null
+++ b/src/nl/astraeus/jdbc/ConnectionLogger.java
@@ -0,0 +1,279 @@
+package nl.astraeus.jdbc;
+
+import java.sql.*;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:12:34 PM
+ */
+public class ConnectionLogger implements Connection {
+ private Connection connection;
+
+ private long milli;
+ private long nano;
+ private String lastSql;
+
+ public ConnectionLogger(Connection connection) {
+ this.connection = connection;
+ this.lastSql = "";
+ }
+
+ private void clearTime() {
+ milli = System.currentTimeMillis();
+ nano = System.nanoTime();
+ }
+
+ private void log(String sql) {
+ long m = System.currentTimeMillis() - milli;
+ long n = System.nanoTime() - nano;
+
+ JdbcLogger.log(QueryType.UNKNOWN, sql, m, n);
+ }
+
+ public void commit() throws SQLException {
+ clearTime();
+
+ connection.commit();
+
+ log("commit");
+ }
+
+ public void rollback() throws SQLException {
+ clearTime();
+
+ connection.rollback();
+
+ log("rollback");
+ }
+
+ public void close() throws SQLException {
+ clearTime();
+
+ connection.close();
+
+ log("close");
+ }
+
+ public PreparedStatement prepareStatement(String sql) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, autoGeneratedKeys);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int columnIndexes[]) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, columnIndexes);
+ }
+
+ public PreparedStatement prepareStatement(String sql, String columnNames[]) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, columnNames);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ public Statement createStatement() throws SQLException {
+ return connection.createStatement();
+ }
+
+ public CallableStatement prepareCall(String sql) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql);
+ }
+
+ public String nativeSQL(String sql) throws SQLException {
+ lastSql = sql;
+ return connection.nativeSQL(sql);
+ }
+
+ public void setAutoCommit(boolean autoCommit) throws SQLException {
+ connection.setAutoCommit(autoCommit);
+ }
+
+ public boolean getAutoCommit() throws SQLException {
+ return connection.getAutoCommit();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return connection.isClosed();
+ }
+
+ public DatabaseMetaData getMetaData() throws SQLException {
+ return connection.getMetaData();
+ }
+
+ public void setReadOnly(boolean readOnly) throws SQLException {
+ connection.setReadOnly(readOnly);
+ }
+
+ public boolean isReadOnly() throws SQLException {
+ return connection.isReadOnly();
+ }
+
+ public void setCatalog(String catalog) throws SQLException {
+ connection.setCatalog(catalog);
+ }
+
+ public String getCatalog() throws SQLException {
+ return connection.getCatalog();
+ }
+
+ public void setTransactionIsolation(int level) throws SQLException {
+ connection.setTransactionIsolation(level);
+ }
+
+ public int getTransactionIsolation() throws SQLException {
+ return connection.getTransactionIsolation();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return connection.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ connection.clearWarnings();
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency);
+ }
+
+ public Map> getTypeMap() throws SQLException {
+ return connection.getTypeMap();
+ }
+
+ public void setTypeMap(Map> map) throws SQLException {
+ connection.setTypeMap(map);
+ }
+
+ public void setHoldability(int holdability) throws SQLException {
+ connection.setHoldability(holdability);
+ }
+
+ public int getHoldability() throws SQLException {
+ return connection.getHoldability();
+ }
+
+ public Savepoint setSavepoint() throws SQLException {
+ return connection.setSavepoint();
+ }
+
+ public Savepoint setSavepoint(String name) throws SQLException {
+ return connection.setSavepoint(name);
+ }
+
+ public void rollback(Savepoint savepoint) throws SQLException {
+ connection.rollback();
+ }
+
+ public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+ connection.releaseSavepoint(savepoint);
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ public Clob createClob() throws SQLException {
+ return connection.createClob();
+ }
+
+ public Blob createBlob() throws SQLException {
+ return connection.createBlob();
+ }
+
+ public NClob createNClob() throws SQLException {
+ return connection.createNClob();
+ }
+
+ public SQLXML createSQLXML() throws SQLException {
+ return connection.createSQLXML();
+ }
+
+ public boolean isValid(int timeout) throws SQLException {
+ return connection.isValid(timeout);
+ }
+
+ public void setClientInfo(String name, String value) throws SQLClientInfoException {
+ connection.setClientInfo(name, value);
+ }
+
+ public void setClientInfo(Properties properties) throws SQLClientInfoException {
+ connection.setClientInfo(properties);
+ }
+
+ public String getClientInfo(String name) throws SQLException {
+ return connection.getClientInfo(name);
+ }
+
+ public Properties getClientInfo() throws SQLException {
+ return connection.getClientInfo();
+ }
+
+ public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
+ return connection.createArrayOf(typeName, elements);
+ }
+
+ public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
+ return connection.createStruct(typeName, attributes);
+ }
+
+ @Override
+ public void setSchema(String schema) throws SQLException {
+ connection.setSchema(schema);
+ }
+
+ @Override
+ public String getSchema() throws SQLException {
+ return connection.getSchema();
+ }
+
+ @Override
+ public void abort(Executor executor) throws SQLException {
+ connection.abort(executor);
+ }
+
+ @Override
+ public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
+ connection.setNetworkTimeout(executor, milliseconds);
+ }
+
+ @Override
+ public int getNetworkTimeout() throws SQLException {
+ return connection.getNetworkTimeout();
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return connection.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return connection.isWrapperFor(iface);
+ }
+}
diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java
new file mode 100644
index 0000000..8317172
--- /dev/null
+++ b/src/nl/astraeus/jdbc/Driver.java
@@ -0,0 +1,116 @@
+package nl.astraeus.jdbc;
+
+import nl.astraeus.http.SimpleWebServer;
+import nl.astraeus.jdbc.web.JdbcStatisticsServlet;
+import nl.astraeus.jdbc.web.ResourceServlet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.*;
+import java.util.Enumeration;
+import java.util.Properties;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:54:37 PM
+ */
+public class Driver implements java.sql.Driver {
+ private final static Logger log = LoggerFactory.getLogger(Driver.class);
+
+ final private static String URL_PREFIX = "jdbc:stat:";
+
+ private java.sql.Driver driver = null;
+ private String[] drivers = {
+ "org.postgresql.Driver",
+ "oracle.jdbc.driver.OracleDriver",
+ "com.sybase.jdbc2.jdbc.SybDriver",
+ "net.sourceforge.jtds.jdbc.Driver",
+ "com.microsoft.jdbc.sqlserver.SQLServerDriver",
+ "com.microsoft.sqlserver.jdbc.SQLServerDriver",
+ "weblogic.jdbc.sqlserver.SQLServerDriver",
+ "com.informix.jdbc.IfxDriver",
+ "org.apache.derby.jdbc.ClientDriver",
+ "org.apache.derby.jdbc.EmbeddedDriver",
+ "com.mysql.jdbc.Driver",
+ "org.hsqldb.jdbcDriver",
+ "org.h2.Driver" };
+
+ static {
+ log.debug("Loading driver class " + Driver.class.getName());
+
+ try {
+ DriverManager.registerDriver(new Driver());
+ } catch (SQLException e) {
+ log.error("", e);
+ }
+ }
+
+ public Driver() {
+ for (String dr : drivers) {
+ try {
+ Class.forName(dr);
+ } catch (Throwable e) {
+ log.debug("Can't instantiate driver: " + dr, e);
+ }
+ }
+ }
+
+ private java.sql.Driver findDriver(String url) throws SQLException {
+ Enumeration e = DriverManager.getDrivers();
+
+ while (e.hasMoreElements()) {
+ java.sql.Driver d = (java.sql.Driver) e.nextElement();
+
+ if (d.acceptsURL(url)) {
+ return d;
+ }
+ }
+
+ throw new SQLException("Driver not found: " + url);
+ }
+
+ public Connection connect(String url, Properties info) throws SQLException {
+ url = url.substring(URL_PREFIX.length());
+
+ if (driver == null) {
+ driver = findDriver(url);
+ }
+
+ if (driver != null) {
+ SimpleWebServer server = new SimpleWebServer(18080);
+
+ server.addServlet(new JdbcStatisticsServlet(), "/");
+ server.addServlet(new ResourceServlet(), "/resources/*");
+
+ server.start();
+ }
+
+ return new ConnectionLogger(driver.connect(url, info));
+ }
+
+ public boolean acceptsURL(String url) throws SQLException {
+ return (url != null && url.startsWith(URL_PREFIX));
+ }
+
+ public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
+ return driver.getPropertyInfo(url, info);
+ }
+
+ public int getMajorVersion() {
+ return driver.getMajorVersion();
+ }
+
+ public int getMinorVersion() {
+ return driver.getMinorVersion();
+ }
+
+ public boolean jdbcCompliant() {
+ return driver.jdbcCompliant();
+ }
+
+ @Override
+ public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ return driver.getParentLogger();
+ }
+}
diff --git a/src/nl/astraeus/jdbc/JdbcLogger.java b/src/nl/astraeus/jdbc/JdbcLogger.java
new file mode 100644
index 0000000..f4bc125
--- /dev/null
+++ b/src/nl/astraeus/jdbc/JdbcLogger.java
@@ -0,0 +1,113 @@
+package nl.astraeus.jdbc;
+
+import nl.astraeus.jdbc.util.Util;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * User: riennentjes
+ * Date: Jul 12, 2008
+ * Time: 9:15:21 AM
+ */
+public class JdbcLogger {
+ private final static Logger logger = LoggerFactory.getLogger(JdbcLogger.class);
+
+ private final static JdbcLogger instance = new JdbcLogger();
+
+ public static JdbcLogger get() {
+ return instance;
+ }
+
+ public final static class LogEntry {
+ public QueryType type;
+ public String sql;
+ public long milli;
+ public long nano;
+ public int count;
+ public int hash;
+
+ public LogEntry(int hash, QueryType type, String sql, long milli, long nano) {
+ this.hash = hash;
+ this.type = type;
+ this.sql = sql;
+ this.milli = milli;
+ this.nano = nano;
+ this.count = 1;
+ }
+
+ public void addCount(long milli, long nano) {
+ synchronized (this) {
+ count++;
+ this.milli += milli;
+ this.nano += nano;
+ }
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public String getMilli() {
+ return Util.formatNano(milli*1000000/count);
+ }
+
+ public String getNano() {
+ return Util.formatNano(nano/count);
+ }
+
+ public String getTotal() {
+ return Util.formatNano(nano);
+ }
+
+ public String getSql() {
+ return sql;
+ }
+ }
+
+ private Map queries;
+
+ public JdbcLogger() {
+ queries = new ConcurrentHashMap();
+ }
+
+ public void logEntry(QueryType type, String sql, long milli, long nano) {
+ int hash = sql.hashCode();
+ LogEntry entry = queries.get(hash);
+
+ if (entry == null) {
+ entry = new LogEntry(hash, type, sql, milli, nano);
+ queries.put(hash, entry);
+ } else {
+ entry.addCount(milli, nano);
+ }
+
+ if (queries.size() > 1000) {
+ List toRemove = new LinkedList();
+ List values = new LinkedList(queries.values());
+
+ Collections.sort(values, new Comparator() {
+ @Override
+ public int compare(LogEntry o1, LogEntry o2) {
+ return o1.count - o2.count;
+ }
+ });
+
+ while (queries.size() > 900) {
+ queries.remove(values.remove(0).hash);
+
+ }
+ }
+ }
+
+ public static void log(QueryType type, String sql, long milli, long nano) {
+ instance.logEntry(type, sql, milli, nano);
+ }
+
+ public Collection getEntries() {
+ return queries.values();
+ }
+
+}
diff --git a/src/nl/astraeus/jdbc/PreparedStatementLogger.java b/src/nl/astraeus/jdbc/PreparedStatementLogger.java
new file mode 100644
index 0000000..98aefc7
--- /dev/null
+++ b/src/nl/astraeus/jdbc/PreparedStatementLogger.java
@@ -0,0 +1,577 @@
+package nl.astraeus.jdbc;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.*;
+import java.util.Calendar;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 7:47:57 PM
+ */
+public class PreparedStatementLogger implements PreparedStatement {
+ private final static Logger log = LoggerFactory.getLogger(PreparedStatementLogger.class);
+
+ private PreparedStatement statement;
+
+ private String sql;
+ private QueryType type;
+ private long milli;
+ private long nano;
+
+ //private ArrayList parameters;
+
+ public PreparedStatementLogger(PreparedStatement statement) {
+ this.statement = statement;
+ this.sql = "";
+ this.type = QueryType.UNKNOWN;
+ }
+
+ private void clearTime() {
+ milli = System.currentTimeMillis();
+ nano = System.nanoTime();
+ }
+
+ private void log(QueryType type, String sql) {
+ long m = System.currentTimeMillis() - milli;
+ long n = System.nanoTime() - nano;
+
+ JdbcLogger.log(type, sql, m, n);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, resultSetType, resultSetConcurrency);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, autoGeneratedKeys);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int[] columnIndexes) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, columnIndexes);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, String[] columnNames) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, columnNames);
+ }
+
+ public boolean execute() throws SQLException {
+ clearTime();
+
+ boolean result = statement.execute();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public ResultSet executeQuery() throws SQLException {
+ clearTime();
+
+ ResultSet result = statement.executeQuery();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate() throws SQLException {
+ clearTime();
+
+ int result = statement.executeUpdate();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public ResultSet executeQuery(String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ ResultSet result = statement.executeQuery(sql);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, autoGeneratedKeys);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, int columnIndexes[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, columnIndexes);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, String columnNames[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, columnNames);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, autoGeneratedKeys);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, int columnIndexes[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, columnIndexes);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, String columnNames[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, columnNames);
+
+ log(type, sql);
+
+ return result;
+ }
+
+
+ public void setNull(int parameterIndex, int sqlType) throws SQLException {
+ statement.setNull(parameterIndex, sqlType);
+ }
+
+ public void setBoolean(int parameterIndex, boolean x) throws SQLException {
+ statement.setBoolean(parameterIndex, x);
+ }
+
+ public void setByte(int parameterIndex, byte x) throws SQLException {
+ statement.setByte(parameterIndex, x);
+ }
+
+ public void setShort(int parameterIndex, short x) throws SQLException {
+ statement.setShort(parameterIndex, x);
+ }
+
+ public void setInt(int parameterIndex, int x) throws SQLException {
+ statement.setInt(parameterIndex, x);
+ }
+
+ public void setLong(int parameterIndex, long x) throws SQLException {
+ statement.setLong(parameterIndex, x);
+ }
+
+ public void setFloat(int parameterIndex, float x) throws SQLException {
+ statement.setFloat(parameterIndex, x);
+ }
+
+ public void setDouble(int parameterIndex, double x) throws SQLException {
+ statement.setDouble(parameterIndex, x);
+ }
+
+ public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
+ statement.setBigDecimal(parameterIndex, x);
+ }
+
+ public void setString(int parameterIndex, String x) throws SQLException {
+ statement.setString(parameterIndex, x);
+ }
+
+ public void setBytes(int parameterIndex, byte x[]) throws SQLException {
+ statement.setBytes(parameterIndex, x);
+ }
+
+ public void setDate(int parameterIndex, Date x) throws SQLException {
+ statement.setDate(parameterIndex, x);
+ }
+
+ public void setTime(int parameterIndex, Time x) throws SQLException {
+ statement.setTime(parameterIndex, x);
+ }
+
+ public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
+ statement.setTimestamp(parameterIndex, x);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x, length);
+ }
+
+ public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setUnicodeStream(parameterIndex, x, length);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x, length);
+ }
+
+ public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
+ statement.setObject(parameterIndex, x, targetSqlType);
+ }
+
+ public void setObject(int parameterIndex, Object x) throws SQLException {
+ statement.setObject(parameterIndex, x);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ public void setRef(int parameterIndex, Ref x) throws SQLException {
+ statement.setRef(parameterIndex, x);
+ }
+
+ public void setBlob(int parameterIndex, Blob x) throws SQLException {
+ statement.setBlob(parameterIndex, x);
+ }
+
+ public void setClob(int parameterIndex, Clob x) throws SQLException {
+ statement.setClob(parameterIndex, x);
+ }
+
+ public void setArray(int parameterIndex, Array x) throws SQLException {
+ statement.setArray(parameterIndex, x);
+ }
+
+ public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
+ statement.setDate(parameterIndex, x, cal);
+ }
+
+ public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
+ statement.setTime(parameterIndex, x, cal);
+ }
+
+ public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
+ statement.setTimestamp(parameterIndex, x, cal);
+ }
+
+ public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
+ statement.setNull(parameterIndex, sqlType, typeName);
+ }
+
+ public void setURL(int parameterIndex, URL x) throws SQLException {
+ statement.setURL(parameterIndex, x);
+ }
+
+ public void setRowId(int parameterIndex, RowId x) throws SQLException {
+ statement.setRowId(parameterIndex, x);
+ }
+
+ public void setNString(int parameterIndex, String value) throws SQLException {
+ statement.setNString(parameterIndex, value);
+ }
+
+ public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
+ statement.setNCharacterStream(parameterIndex, value, length);
+ }
+
+ public void setNClob(int parameterIndex, NClob value) throws SQLException {
+ statement.setNClob(parameterIndex, value);
+ }
+
+ public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setClob(parameterIndex, reader, length);
+ }
+
+ public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
+ statement.setBlob(parameterIndex, inputStream, length);
+ }
+
+ public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setNClob(parameterIndex, reader, length);
+ }
+
+ public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
+ statement.setSQLXML(parameterIndex, xmlObject);
+ }
+
+ public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException {
+ statement.setObject(parameterIndex, x, targetSqlType, scaleOrLength);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x, length);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x, length);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader);
+ }
+
+ public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
+ statement.setNCharacterStream(parameterIndex, value);
+ }
+
+ public void setClob(int parameterIndex, Reader reader) throws SQLException {
+ statement.setClob(parameterIndex, reader);
+ }
+
+ public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
+ statement.setBlob(parameterIndex, inputStream);
+ }
+
+ public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+ statement.setNClob(parameterIndex, reader);
+ }
+
+
+ public void close() throws SQLException {
+ sql = "";
+ type = QueryType.UNKNOWN;
+ milli = 0;
+ nano = 0;
+
+ statement.close();
+ }
+
+ public ResultSetMetaData getMetaData() throws SQLException {
+ return statement.getMetaData();
+ }
+
+ public void clearParameters() throws SQLException {
+ statement.clearParameters();
+ }
+
+ public ParameterMetaData getParameterMetaData() throws SQLException {
+ return statement.getParameterMetaData();
+ }
+
+ public void addBatch() throws SQLException {
+ statement.addBatch();
+ }
+
+ public int getMaxFieldSize() throws SQLException {
+ return statement.getMaxFieldSize();
+ }
+
+ public void setMaxFieldSize(int max) throws SQLException {
+ statement.setMaxFieldSize(max);
+ }
+
+ public int getMaxRows() throws SQLException {
+ return statement.getMaxRows();
+ }
+
+ public void setMaxRows(int max) throws SQLException {
+ statement.setMaxRows(max);
+ }
+
+ public void setEscapeProcessing(boolean enable) throws SQLException {
+ statement.setEscapeProcessing(enable);
+ }
+
+ public int getQueryTimeout() throws SQLException {
+ return statement.getQueryTimeout();
+ }
+
+ public void setQueryTimeout(int seconds) throws SQLException {
+ statement.setQueryTimeout(seconds);
+ }
+
+ public void cancel() throws SQLException {
+ statement.cancel();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return statement.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ statement.clearWarnings();
+ }
+
+ public void setCursorName(String name) throws SQLException {
+ statement.setCursorName(name);
+ }
+
+ public boolean execute(String sql) throws SQLException {
+ return statement.execute(sql);
+ }
+
+ public ResultSet getResultSet() throws SQLException {
+ return statement.getResultSet();
+ }
+
+ public int getUpdateCount() throws SQLException {
+ return statement.getUpdateCount();
+ }
+
+ public boolean getMoreResults() throws SQLException {
+ return statement.getMoreResults();
+ }
+
+ public void setFetchDirection(int direction) throws SQLException {
+ statement.setFetchDirection(direction);
+ }
+
+ public int getFetchDirection() throws SQLException {
+ return statement.getFetchDirection();
+ }
+
+ public void setFetchSize(int rows) throws SQLException {
+ statement.setFetchSize(rows);
+ }
+
+ public int getFetchSize() throws SQLException {
+ return statement.getFetchSize();
+ }
+
+ public int getResultSetConcurrency() throws SQLException {
+ return statement.getResultSetConcurrency();
+ }
+
+ public int getResultSetType() throws SQLException {
+ return statement.getResultSetType();
+ }
+
+ public void addBatch(String sql) throws SQLException {
+ statement.addBatch(sql);
+ }
+
+ public void clearBatch() throws SQLException {
+ statement.clearBatch();
+ }
+
+ public int[] executeBatch() throws SQLException {
+ return statement.executeBatch();
+ }
+
+ public Connection getConnection() throws SQLException {
+ return statement.getConnection();
+ }
+
+ public boolean getMoreResults(int current) throws SQLException {
+ return statement.getMoreResults(current);
+ }
+
+ public ResultSet getGeneratedKeys() throws SQLException {
+ return statement.getGeneratedKeys();
+ }
+
+ public int getResultSetHoldability() throws SQLException {
+ return statement.getResultSetHoldability();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return statement.isClosed();
+ }
+
+ public void setPoolable(boolean poolable) throws SQLException {
+ statement.setPoolable(poolable);
+ }
+
+ public boolean isPoolable() throws SQLException {
+ return statement.isPoolable();
+ }
+
+ @Override
+ public void closeOnCompletion() throws SQLException {
+ statement.closeOnCompletion();;
+ }
+
+ @Override
+ public boolean isCloseOnCompletion() throws SQLException {
+ return statement.isCloseOnCompletion();
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return statement.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return statement.isWrapperFor(iface);
+ }
+}
diff --git a/src/nl/astraeus/jdbc/QueryType.java b/src/nl/astraeus/jdbc/QueryType.java
new file mode 100644
index 0000000..744fbfc
--- /dev/null
+++ b/src/nl/astraeus/jdbc/QueryType.java
@@ -0,0 +1,24 @@
+package nl.astraeus.jdbc;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:32:49 PM
+ */
+public enum QueryType {
+ PLAIN("plain"),
+ PREPARED("prepared"),
+ CALLABLE("callable"),
+ UNKNOWN("unknown");
+
+ private String description;
+
+ QueryType(String description) {
+ this.description = description;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+}
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..275077f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README b/README
deleted file mode 100644
index 734abaf..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-This file was created by IntelliJ IDEA 11.1.1 for binding GitHub repository
\ No newline at end of file
diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml
new file mode 100644
index 0000000..ca90a9b
--- /dev/null
+++ b/Simple-jdbc-statistics.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/h2-1.3.166.jar b/lib/h2-1.3.166.jar
new file mode 100644
index 0000000..4985063
--- /dev/null
+++ b/lib/h2-1.3.166.jar
Binary files differ
diff --git a/lib/servlet-api-2.5.jar b/lib/servlet-api-2.5.jar
new file mode 100644
index 0000000..20b5755
--- /dev/null
+++ b/lib/servlet-api-2.5.jar
Binary files differ
diff --git a/lib/slf4j-api-1.6.4.jar b/lib/slf4j-api-1.6.4.jar
new file mode 100644
index 0000000..4d23f41
--- /dev/null
+++ b/lib/slf4j-api-1.6.4.jar
Binary files differ
diff --git a/lib/slf4j-simple-1.6.4.jar b/lib/slf4j-simple-1.6.4.jar
new file mode 100644
index 0000000..3d1b8d9
--- /dev/null
+++ b/lib/slf4j-simple-1.6.4.jar
Binary files differ
diff --git a/lib/ssr-0.1.jar b/lib/ssr-0.1.jar
new file mode 100644
index 0000000..65dfcf4
--- /dev/null
+++ b/lib/ssr-0.1.jar
Binary files differ
diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar
new file mode 100644
index 0000000..db63792
--- /dev/null
+++ b/lib/vst-0.4.jar
Binary files differ
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..ac2dbe1
--- /dev/null
+++ b/readme.md
@@ -0,0 +1 @@
+A simple wrapper around jdbc drivers what will show current jdbc stats of the running queries on a simple web page on port 18080.
\ No newline at end of file
diff --git a/src/nl/astraeus/jdbc/ConnectionLogger.java b/src/nl/astraeus/jdbc/ConnectionLogger.java
new file mode 100644
index 0000000..c3e243f
--- /dev/null
+++ b/src/nl/astraeus/jdbc/ConnectionLogger.java
@@ -0,0 +1,279 @@
+package nl.astraeus.jdbc;
+
+import java.sql.*;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:12:34 PM
+ */
+public class ConnectionLogger implements Connection {
+ private Connection connection;
+
+ private long milli;
+ private long nano;
+ private String lastSql;
+
+ public ConnectionLogger(Connection connection) {
+ this.connection = connection;
+ this.lastSql = "";
+ }
+
+ private void clearTime() {
+ milli = System.currentTimeMillis();
+ nano = System.nanoTime();
+ }
+
+ private void log(String sql) {
+ long m = System.currentTimeMillis() - milli;
+ long n = System.nanoTime() - nano;
+
+ JdbcLogger.log(QueryType.UNKNOWN, sql, m, n);
+ }
+
+ public void commit() throws SQLException {
+ clearTime();
+
+ connection.commit();
+
+ log("commit");
+ }
+
+ public void rollback() throws SQLException {
+ clearTime();
+
+ connection.rollback();
+
+ log("rollback");
+ }
+
+ public void close() throws SQLException {
+ clearTime();
+
+ connection.close();
+
+ log("close");
+ }
+
+ public PreparedStatement prepareStatement(String sql) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, autoGeneratedKeys);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int columnIndexes[]) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, columnIndexes);
+ }
+
+ public PreparedStatement prepareStatement(String sql, String columnNames[]) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, columnNames);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ public Statement createStatement() throws SQLException {
+ return connection.createStatement();
+ }
+
+ public CallableStatement prepareCall(String sql) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql);
+ }
+
+ public String nativeSQL(String sql) throws SQLException {
+ lastSql = sql;
+ return connection.nativeSQL(sql);
+ }
+
+ public void setAutoCommit(boolean autoCommit) throws SQLException {
+ connection.setAutoCommit(autoCommit);
+ }
+
+ public boolean getAutoCommit() throws SQLException {
+ return connection.getAutoCommit();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return connection.isClosed();
+ }
+
+ public DatabaseMetaData getMetaData() throws SQLException {
+ return connection.getMetaData();
+ }
+
+ public void setReadOnly(boolean readOnly) throws SQLException {
+ connection.setReadOnly(readOnly);
+ }
+
+ public boolean isReadOnly() throws SQLException {
+ return connection.isReadOnly();
+ }
+
+ public void setCatalog(String catalog) throws SQLException {
+ connection.setCatalog(catalog);
+ }
+
+ public String getCatalog() throws SQLException {
+ return connection.getCatalog();
+ }
+
+ public void setTransactionIsolation(int level) throws SQLException {
+ connection.setTransactionIsolation(level);
+ }
+
+ public int getTransactionIsolation() throws SQLException {
+ return connection.getTransactionIsolation();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return connection.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ connection.clearWarnings();
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency);
+ }
+
+ public Map> getTypeMap() throws SQLException {
+ return connection.getTypeMap();
+ }
+
+ public void setTypeMap(Map> map) throws SQLException {
+ connection.setTypeMap(map);
+ }
+
+ public void setHoldability(int holdability) throws SQLException {
+ connection.setHoldability(holdability);
+ }
+
+ public int getHoldability() throws SQLException {
+ return connection.getHoldability();
+ }
+
+ public Savepoint setSavepoint() throws SQLException {
+ return connection.setSavepoint();
+ }
+
+ public Savepoint setSavepoint(String name) throws SQLException {
+ return connection.setSavepoint(name);
+ }
+
+ public void rollback(Savepoint savepoint) throws SQLException {
+ connection.rollback();
+ }
+
+ public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+ connection.releaseSavepoint(savepoint);
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ public Clob createClob() throws SQLException {
+ return connection.createClob();
+ }
+
+ public Blob createBlob() throws SQLException {
+ return connection.createBlob();
+ }
+
+ public NClob createNClob() throws SQLException {
+ return connection.createNClob();
+ }
+
+ public SQLXML createSQLXML() throws SQLException {
+ return connection.createSQLXML();
+ }
+
+ public boolean isValid(int timeout) throws SQLException {
+ return connection.isValid(timeout);
+ }
+
+ public void setClientInfo(String name, String value) throws SQLClientInfoException {
+ connection.setClientInfo(name, value);
+ }
+
+ public void setClientInfo(Properties properties) throws SQLClientInfoException {
+ connection.setClientInfo(properties);
+ }
+
+ public String getClientInfo(String name) throws SQLException {
+ return connection.getClientInfo(name);
+ }
+
+ public Properties getClientInfo() throws SQLException {
+ return connection.getClientInfo();
+ }
+
+ public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
+ return connection.createArrayOf(typeName, elements);
+ }
+
+ public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
+ return connection.createStruct(typeName, attributes);
+ }
+
+ @Override
+ public void setSchema(String schema) throws SQLException {
+ connection.setSchema(schema);
+ }
+
+ @Override
+ public String getSchema() throws SQLException {
+ return connection.getSchema();
+ }
+
+ @Override
+ public void abort(Executor executor) throws SQLException {
+ connection.abort(executor);
+ }
+
+ @Override
+ public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
+ connection.setNetworkTimeout(executor, milliseconds);
+ }
+
+ @Override
+ public int getNetworkTimeout() throws SQLException {
+ return connection.getNetworkTimeout();
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return connection.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return connection.isWrapperFor(iface);
+ }
+}
diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java
new file mode 100644
index 0000000..8317172
--- /dev/null
+++ b/src/nl/astraeus/jdbc/Driver.java
@@ -0,0 +1,116 @@
+package nl.astraeus.jdbc;
+
+import nl.astraeus.http.SimpleWebServer;
+import nl.astraeus.jdbc.web.JdbcStatisticsServlet;
+import nl.astraeus.jdbc.web.ResourceServlet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.*;
+import java.util.Enumeration;
+import java.util.Properties;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:54:37 PM
+ */
+public class Driver implements java.sql.Driver {
+ private final static Logger log = LoggerFactory.getLogger(Driver.class);
+
+ final private static String URL_PREFIX = "jdbc:stat:";
+
+ private java.sql.Driver driver = null;
+ private String[] drivers = {
+ "org.postgresql.Driver",
+ "oracle.jdbc.driver.OracleDriver",
+ "com.sybase.jdbc2.jdbc.SybDriver",
+ "net.sourceforge.jtds.jdbc.Driver",
+ "com.microsoft.jdbc.sqlserver.SQLServerDriver",
+ "com.microsoft.sqlserver.jdbc.SQLServerDriver",
+ "weblogic.jdbc.sqlserver.SQLServerDriver",
+ "com.informix.jdbc.IfxDriver",
+ "org.apache.derby.jdbc.ClientDriver",
+ "org.apache.derby.jdbc.EmbeddedDriver",
+ "com.mysql.jdbc.Driver",
+ "org.hsqldb.jdbcDriver",
+ "org.h2.Driver" };
+
+ static {
+ log.debug("Loading driver class " + Driver.class.getName());
+
+ try {
+ DriverManager.registerDriver(new Driver());
+ } catch (SQLException e) {
+ log.error("", e);
+ }
+ }
+
+ public Driver() {
+ for (String dr : drivers) {
+ try {
+ Class.forName(dr);
+ } catch (Throwable e) {
+ log.debug("Can't instantiate driver: " + dr, e);
+ }
+ }
+ }
+
+ private java.sql.Driver findDriver(String url) throws SQLException {
+ Enumeration e = DriverManager.getDrivers();
+
+ while (e.hasMoreElements()) {
+ java.sql.Driver d = (java.sql.Driver) e.nextElement();
+
+ if (d.acceptsURL(url)) {
+ return d;
+ }
+ }
+
+ throw new SQLException("Driver not found: " + url);
+ }
+
+ public Connection connect(String url, Properties info) throws SQLException {
+ url = url.substring(URL_PREFIX.length());
+
+ if (driver == null) {
+ driver = findDriver(url);
+ }
+
+ if (driver != null) {
+ SimpleWebServer server = new SimpleWebServer(18080);
+
+ server.addServlet(new JdbcStatisticsServlet(), "/");
+ server.addServlet(new ResourceServlet(), "/resources/*");
+
+ server.start();
+ }
+
+ return new ConnectionLogger(driver.connect(url, info));
+ }
+
+ public boolean acceptsURL(String url) throws SQLException {
+ return (url != null && url.startsWith(URL_PREFIX));
+ }
+
+ public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
+ return driver.getPropertyInfo(url, info);
+ }
+
+ public int getMajorVersion() {
+ return driver.getMajorVersion();
+ }
+
+ public int getMinorVersion() {
+ return driver.getMinorVersion();
+ }
+
+ public boolean jdbcCompliant() {
+ return driver.jdbcCompliant();
+ }
+
+ @Override
+ public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ return driver.getParentLogger();
+ }
+}
diff --git a/src/nl/astraeus/jdbc/JdbcLogger.java b/src/nl/astraeus/jdbc/JdbcLogger.java
new file mode 100644
index 0000000..f4bc125
--- /dev/null
+++ b/src/nl/astraeus/jdbc/JdbcLogger.java
@@ -0,0 +1,113 @@
+package nl.astraeus.jdbc;
+
+import nl.astraeus.jdbc.util.Util;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * User: riennentjes
+ * Date: Jul 12, 2008
+ * Time: 9:15:21 AM
+ */
+public class JdbcLogger {
+ private final static Logger logger = LoggerFactory.getLogger(JdbcLogger.class);
+
+ private final static JdbcLogger instance = new JdbcLogger();
+
+ public static JdbcLogger get() {
+ return instance;
+ }
+
+ public final static class LogEntry {
+ public QueryType type;
+ public String sql;
+ public long milli;
+ public long nano;
+ public int count;
+ public int hash;
+
+ public LogEntry(int hash, QueryType type, String sql, long milli, long nano) {
+ this.hash = hash;
+ this.type = type;
+ this.sql = sql;
+ this.milli = milli;
+ this.nano = nano;
+ this.count = 1;
+ }
+
+ public void addCount(long milli, long nano) {
+ synchronized (this) {
+ count++;
+ this.milli += milli;
+ this.nano += nano;
+ }
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public String getMilli() {
+ return Util.formatNano(milli*1000000/count);
+ }
+
+ public String getNano() {
+ return Util.formatNano(nano/count);
+ }
+
+ public String getTotal() {
+ return Util.formatNano(nano);
+ }
+
+ public String getSql() {
+ return sql;
+ }
+ }
+
+ private Map queries;
+
+ public JdbcLogger() {
+ queries = new ConcurrentHashMap();
+ }
+
+ public void logEntry(QueryType type, String sql, long milli, long nano) {
+ int hash = sql.hashCode();
+ LogEntry entry = queries.get(hash);
+
+ if (entry == null) {
+ entry = new LogEntry(hash, type, sql, milli, nano);
+ queries.put(hash, entry);
+ } else {
+ entry.addCount(milli, nano);
+ }
+
+ if (queries.size() > 1000) {
+ List toRemove = new LinkedList();
+ List values = new LinkedList(queries.values());
+
+ Collections.sort(values, new Comparator() {
+ @Override
+ public int compare(LogEntry o1, LogEntry o2) {
+ return o1.count - o2.count;
+ }
+ });
+
+ while (queries.size() > 900) {
+ queries.remove(values.remove(0).hash);
+
+ }
+ }
+ }
+
+ public static void log(QueryType type, String sql, long milli, long nano) {
+ instance.logEntry(type, sql, milli, nano);
+ }
+
+ public Collection getEntries() {
+ return queries.values();
+ }
+
+}
diff --git a/src/nl/astraeus/jdbc/PreparedStatementLogger.java b/src/nl/astraeus/jdbc/PreparedStatementLogger.java
new file mode 100644
index 0000000..98aefc7
--- /dev/null
+++ b/src/nl/astraeus/jdbc/PreparedStatementLogger.java
@@ -0,0 +1,577 @@
+package nl.astraeus.jdbc;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.*;
+import java.util.Calendar;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 7:47:57 PM
+ */
+public class PreparedStatementLogger implements PreparedStatement {
+ private final static Logger log = LoggerFactory.getLogger(PreparedStatementLogger.class);
+
+ private PreparedStatement statement;
+
+ private String sql;
+ private QueryType type;
+ private long milli;
+ private long nano;
+
+ //private ArrayList parameters;
+
+ public PreparedStatementLogger(PreparedStatement statement) {
+ this.statement = statement;
+ this.sql = "";
+ this.type = QueryType.UNKNOWN;
+ }
+
+ private void clearTime() {
+ milli = System.currentTimeMillis();
+ nano = System.nanoTime();
+ }
+
+ private void log(QueryType type, String sql) {
+ long m = System.currentTimeMillis() - milli;
+ long n = System.nanoTime() - nano;
+
+ JdbcLogger.log(type, sql, m, n);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, resultSetType, resultSetConcurrency);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, autoGeneratedKeys);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int[] columnIndexes) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, columnIndexes);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, String[] columnNames) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, columnNames);
+ }
+
+ public boolean execute() throws SQLException {
+ clearTime();
+
+ boolean result = statement.execute();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public ResultSet executeQuery() throws SQLException {
+ clearTime();
+
+ ResultSet result = statement.executeQuery();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate() throws SQLException {
+ clearTime();
+
+ int result = statement.executeUpdate();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public ResultSet executeQuery(String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ ResultSet result = statement.executeQuery(sql);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, autoGeneratedKeys);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, int columnIndexes[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, columnIndexes);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, String columnNames[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, columnNames);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, autoGeneratedKeys);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, int columnIndexes[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, columnIndexes);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, String columnNames[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, columnNames);
+
+ log(type, sql);
+
+ return result;
+ }
+
+
+ public void setNull(int parameterIndex, int sqlType) throws SQLException {
+ statement.setNull(parameterIndex, sqlType);
+ }
+
+ public void setBoolean(int parameterIndex, boolean x) throws SQLException {
+ statement.setBoolean(parameterIndex, x);
+ }
+
+ public void setByte(int parameterIndex, byte x) throws SQLException {
+ statement.setByte(parameterIndex, x);
+ }
+
+ public void setShort(int parameterIndex, short x) throws SQLException {
+ statement.setShort(parameterIndex, x);
+ }
+
+ public void setInt(int parameterIndex, int x) throws SQLException {
+ statement.setInt(parameterIndex, x);
+ }
+
+ public void setLong(int parameterIndex, long x) throws SQLException {
+ statement.setLong(parameterIndex, x);
+ }
+
+ public void setFloat(int parameterIndex, float x) throws SQLException {
+ statement.setFloat(parameterIndex, x);
+ }
+
+ public void setDouble(int parameterIndex, double x) throws SQLException {
+ statement.setDouble(parameterIndex, x);
+ }
+
+ public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
+ statement.setBigDecimal(parameterIndex, x);
+ }
+
+ public void setString(int parameterIndex, String x) throws SQLException {
+ statement.setString(parameterIndex, x);
+ }
+
+ public void setBytes(int parameterIndex, byte x[]) throws SQLException {
+ statement.setBytes(parameterIndex, x);
+ }
+
+ public void setDate(int parameterIndex, Date x) throws SQLException {
+ statement.setDate(parameterIndex, x);
+ }
+
+ public void setTime(int parameterIndex, Time x) throws SQLException {
+ statement.setTime(parameterIndex, x);
+ }
+
+ public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
+ statement.setTimestamp(parameterIndex, x);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x, length);
+ }
+
+ public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setUnicodeStream(parameterIndex, x, length);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x, length);
+ }
+
+ public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
+ statement.setObject(parameterIndex, x, targetSqlType);
+ }
+
+ public void setObject(int parameterIndex, Object x) throws SQLException {
+ statement.setObject(parameterIndex, x);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ public void setRef(int parameterIndex, Ref x) throws SQLException {
+ statement.setRef(parameterIndex, x);
+ }
+
+ public void setBlob(int parameterIndex, Blob x) throws SQLException {
+ statement.setBlob(parameterIndex, x);
+ }
+
+ public void setClob(int parameterIndex, Clob x) throws SQLException {
+ statement.setClob(parameterIndex, x);
+ }
+
+ public void setArray(int parameterIndex, Array x) throws SQLException {
+ statement.setArray(parameterIndex, x);
+ }
+
+ public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
+ statement.setDate(parameterIndex, x, cal);
+ }
+
+ public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
+ statement.setTime(parameterIndex, x, cal);
+ }
+
+ public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
+ statement.setTimestamp(parameterIndex, x, cal);
+ }
+
+ public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
+ statement.setNull(parameterIndex, sqlType, typeName);
+ }
+
+ public void setURL(int parameterIndex, URL x) throws SQLException {
+ statement.setURL(parameterIndex, x);
+ }
+
+ public void setRowId(int parameterIndex, RowId x) throws SQLException {
+ statement.setRowId(parameterIndex, x);
+ }
+
+ public void setNString(int parameterIndex, String value) throws SQLException {
+ statement.setNString(parameterIndex, value);
+ }
+
+ public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
+ statement.setNCharacterStream(parameterIndex, value, length);
+ }
+
+ public void setNClob(int parameterIndex, NClob value) throws SQLException {
+ statement.setNClob(parameterIndex, value);
+ }
+
+ public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setClob(parameterIndex, reader, length);
+ }
+
+ public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
+ statement.setBlob(parameterIndex, inputStream, length);
+ }
+
+ public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setNClob(parameterIndex, reader, length);
+ }
+
+ public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
+ statement.setSQLXML(parameterIndex, xmlObject);
+ }
+
+ public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException {
+ statement.setObject(parameterIndex, x, targetSqlType, scaleOrLength);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x, length);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x, length);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader);
+ }
+
+ public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
+ statement.setNCharacterStream(parameterIndex, value);
+ }
+
+ public void setClob(int parameterIndex, Reader reader) throws SQLException {
+ statement.setClob(parameterIndex, reader);
+ }
+
+ public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
+ statement.setBlob(parameterIndex, inputStream);
+ }
+
+ public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+ statement.setNClob(parameterIndex, reader);
+ }
+
+
+ public void close() throws SQLException {
+ sql = "";
+ type = QueryType.UNKNOWN;
+ milli = 0;
+ nano = 0;
+
+ statement.close();
+ }
+
+ public ResultSetMetaData getMetaData() throws SQLException {
+ return statement.getMetaData();
+ }
+
+ public void clearParameters() throws SQLException {
+ statement.clearParameters();
+ }
+
+ public ParameterMetaData getParameterMetaData() throws SQLException {
+ return statement.getParameterMetaData();
+ }
+
+ public void addBatch() throws SQLException {
+ statement.addBatch();
+ }
+
+ public int getMaxFieldSize() throws SQLException {
+ return statement.getMaxFieldSize();
+ }
+
+ public void setMaxFieldSize(int max) throws SQLException {
+ statement.setMaxFieldSize(max);
+ }
+
+ public int getMaxRows() throws SQLException {
+ return statement.getMaxRows();
+ }
+
+ public void setMaxRows(int max) throws SQLException {
+ statement.setMaxRows(max);
+ }
+
+ public void setEscapeProcessing(boolean enable) throws SQLException {
+ statement.setEscapeProcessing(enable);
+ }
+
+ public int getQueryTimeout() throws SQLException {
+ return statement.getQueryTimeout();
+ }
+
+ public void setQueryTimeout(int seconds) throws SQLException {
+ statement.setQueryTimeout(seconds);
+ }
+
+ public void cancel() throws SQLException {
+ statement.cancel();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return statement.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ statement.clearWarnings();
+ }
+
+ public void setCursorName(String name) throws SQLException {
+ statement.setCursorName(name);
+ }
+
+ public boolean execute(String sql) throws SQLException {
+ return statement.execute(sql);
+ }
+
+ public ResultSet getResultSet() throws SQLException {
+ return statement.getResultSet();
+ }
+
+ public int getUpdateCount() throws SQLException {
+ return statement.getUpdateCount();
+ }
+
+ public boolean getMoreResults() throws SQLException {
+ return statement.getMoreResults();
+ }
+
+ public void setFetchDirection(int direction) throws SQLException {
+ statement.setFetchDirection(direction);
+ }
+
+ public int getFetchDirection() throws SQLException {
+ return statement.getFetchDirection();
+ }
+
+ public void setFetchSize(int rows) throws SQLException {
+ statement.setFetchSize(rows);
+ }
+
+ public int getFetchSize() throws SQLException {
+ return statement.getFetchSize();
+ }
+
+ public int getResultSetConcurrency() throws SQLException {
+ return statement.getResultSetConcurrency();
+ }
+
+ public int getResultSetType() throws SQLException {
+ return statement.getResultSetType();
+ }
+
+ public void addBatch(String sql) throws SQLException {
+ statement.addBatch(sql);
+ }
+
+ public void clearBatch() throws SQLException {
+ statement.clearBatch();
+ }
+
+ public int[] executeBatch() throws SQLException {
+ return statement.executeBatch();
+ }
+
+ public Connection getConnection() throws SQLException {
+ return statement.getConnection();
+ }
+
+ public boolean getMoreResults(int current) throws SQLException {
+ return statement.getMoreResults(current);
+ }
+
+ public ResultSet getGeneratedKeys() throws SQLException {
+ return statement.getGeneratedKeys();
+ }
+
+ public int getResultSetHoldability() throws SQLException {
+ return statement.getResultSetHoldability();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return statement.isClosed();
+ }
+
+ public void setPoolable(boolean poolable) throws SQLException {
+ statement.setPoolable(poolable);
+ }
+
+ public boolean isPoolable() throws SQLException {
+ return statement.isPoolable();
+ }
+
+ @Override
+ public void closeOnCompletion() throws SQLException {
+ statement.closeOnCompletion();;
+ }
+
+ @Override
+ public boolean isCloseOnCompletion() throws SQLException {
+ return statement.isCloseOnCompletion();
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return statement.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return statement.isWrapperFor(iface);
+ }
+}
diff --git a/src/nl/astraeus/jdbc/QueryType.java b/src/nl/astraeus/jdbc/QueryType.java
new file mode 100644
index 0000000..744fbfc
--- /dev/null
+++ b/src/nl/astraeus/jdbc/QueryType.java
@@ -0,0 +1,24 @@
+package nl.astraeus.jdbc;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:32:49 PM
+ */
+public enum QueryType {
+ PLAIN("plain"),
+ PREPARED("prepared"),
+ CALLABLE("callable"),
+ UNKNOWN("unknown");
+
+ private String description;
+
+ QueryType(String description) {
+ this.description = description;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+}
diff --git a/src/nl/astraeus/jdbc/example/JdbcStatisticsExample.java b/src/nl/astraeus/jdbc/example/JdbcStatisticsExample.java
new file mode 100644
index 0000000..07aac40
--- /dev/null
+++ b/src/nl/astraeus/jdbc/example/JdbcStatisticsExample.java
@@ -0,0 +1,68 @@
+package nl.astraeus.jdbc.example;
+
+import java.sql.*;
+
+/**
+ * User: rnentjes
+ * Date: 4/12/12
+ * Time: 7:32 PM
+ */
+public class JdbcStatisticsExample {
+
+
+ public static void main(String [] args) throws Exception {
+ Class.forName("org.h2.Driver");
+ Class.forName("nl.astraeus.jdbc.Driver");
+
+ new JdbcStatisticsExample();
+ }
+
+ public JdbcStatisticsExample() throws Exception {
+ Connection conn = DriverManager.getConnection("jdbc:stat:jdbc:h2:mem:test");
+
+ Statement statement = null;
+
+ statement = conn.createStatement();
+ statement.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))");
+ statement.close();
+
+ boolean running = true;
+ int count = 1;
+ PreparedStatement ps = null;
+
+ while (running) {
+ Thread.sleep(10);
+
+ String TableName = "TEST"+(System.nanoTime() % 1000);
+
+ try {
+ ps = conn.prepareStatement("SELECT COUNT(*) FROM "+TableName);
+ ResultSet rs = ps.executeQuery();
+ } catch (SQLException e) {
+ statement = conn.createStatement();
+ statement.execute("CREATE TABLE "+TableName+" (ID INT PRIMARY KEY, NAME VARCHAR(255))");
+ statement.close();
+ } finally {
+ if (ps!=null) {
+ ps.close();
+ }
+ }
+
+ ps = conn.prepareStatement("INSERT INTO "+TableName+" VALUES (?, ?)");
+
+ ps.setInt(1, count++);
+ ps.setString(2, "String "+System.currentTimeMillis());
+
+ ps.execute();
+ ps.close();
+
+ Thread.sleep(10);
+
+ ps = conn.prepareStatement("SELECT * FROM "+TableName);
+ ResultSet rs = ps.executeQuery();
+ statement.close();
+ }
+
+ conn.close();
+ }
+}
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..275077f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README b/README
deleted file mode 100644
index 734abaf..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-This file was created by IntelliJ IDEA 11.1.1 for binding GitHub repository
\ No newline at end of file
diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml
new file mode 100644
index 0000000..ca90a9b
--- /dev/null
+++ b/Simple-jdbc-statistics.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/h2-1.3.166.jar b/lib/h2-1.3.166.jar
new file mode 100644
index 0000000..4985063
--- /dev/null
+++ b/lib/h2-1.3.166.jar
Binary files differ
diff --git a/lib/servlet-api-2.5.jar b/lib/servlet-api-2.5.jar
new file mode 100644
index 0000000..20b5755
--- /dev/null
+++ b/lib/servlet-api-2.5.jar
Binary files differ
diff --git a/lib/slf4j-api-1.6.4.jar b/lib/slf4j-api-1.6.4.jar
new file mode 100644
index 0000000..4d23f41
--- /dev/null
+++ b/lib/slf4j-api-1.6.4.jar
Binary files differ
diff --git a/lib/slf4j-simple-1.6.4.jar b/lib/slf4j-simple-1.6.4.jar
new file mode 100644
index 0000000..3d1b8d9
--- /dev/null
+++ b/lib/slf4j-simple-1.6.4.jar
Binary files differ
diff --git a/lib/ssr-0.1.jar b/lib/ssr-0.1.jar
new file mode 100644
index 0000000..65dfcf4
--- /dev/null
+++ b/lib/ssr-0.1.jar
Binary files differ
diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar
new file mode 100644
index 0000000..db63792
--- /dev/null
+++ b/lib/vst-0.4.jar
Binary files differ
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..ac2dbe1
--- /dev/null
+++ b/readme.md
@@ -0,0 +1 @@
+A simple wrapper around jdbc drivers what will show current jdbc stats of the running queries on a simple web page on port 18080.
\ No newline at end of file
diff --git a/src/nl/astraeus/jdbc/ConnectionLogger.java b/src/nl/astraeus/jdbc/ConnectionLogger.java
new file mode 100644
index 0000000..c3e243f
--- /dev/null
+++ b/src/nl/astraeus/jdbc/ConnectionLogger.java
@@ -0,0 +1,279 @@
+package nl.astraeus.jdbc;
+
+import java.sql.*;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:12:34 PM
+ */
+public class ConnectionLogger implements Connection {
+ private Connection connection;
+
+ private long milli;
+ private long nano;
+ private String lastSql;
+
+ public ConnectionLogger(Connection connection) {
+ this.connection = connection;
+ this.lastSql = "";
+ }
+
+ private void clearTime() {
+ milli = System.currentTimeMillis();
+ nano = System.nanoTime();
+ }
+
+ private void log(String sql) {
+ long m = System.currentTimeMillis() - milli;
+ long n = System.nanoTime() - nano;
+
+ JdbcLogger.log(QueryType.UNKNOWN, sql, m, n);
+ }
+
+ public void commit() throws SQLException {
+ clearTime();
+
+ connection.commit();
+
+ log("commit");
+ }
+
+ public void rollback() throws SQLException {
+ clearTime();
+
+ connection.rollback();
+
+ log("rollback");
+ }
+
+ public void close() throws SQLException {
+ clearTime();
+
+ connection.close();
+
+ log("close");
+ }
+
+ public PreparedStatement prepareStatement(String sql) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, autoGeneratedKeys);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int columnIndexes[]) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, columnIndexes);
+ }
+
+ public PreparedStatement prepareStatement(String sql, String columnNames[]) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, columnNames);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ public Statement createStatement() throws SQLException {
+ return connection.createStatement();
+ }
+
+ public CallableStatement prepareCall(String sql) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql);
+ }
+
+ public String nativeSQL(String sql) throws SQLException {
+ lastSql = sql;
+ return connection.nativeSQL(sql);
+ }
+
+ public void setAutoCommit(boolean autoCommit) throws SQLException {
+ connection.setAutoCommit(autoCommit);
+ }
+
+ public boolean getAutoCommit() throws SQLException {
+ return connection.getAutoCommit();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return connection.isClosed();
+ }
+
+ public DatabaseMetaData getMetaData() throws SQLException {
+ return connection.getMetaData();
+ }
+
+ public void setReadOnly(boolean readOnly) throws SQLException {
+ connection.setReadOnly(readOnly);
+ }
+
+ public boolean isReadOnly() throws SQLException {
+ return connection.isReadOnly();
+ }
+
+ public void setCatalog(String catalog) throws SQLException {
+ connection.setCatalog(catalog);
+ }
+
+ public String getCatalog() throws SQLException {
+ return connection.getCatalog();
+ }
+
+ public void setTransactionIsolation(int level) throws SQLException {
+ connection.setTransactionIsolation(level);
+ }
+
+ public int getTransactionIsolation() throws SQLException {
+ return connection.getTransactionIsolation();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return connection.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ connection.clearWarnings();
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency);
+ }
+
+ public Map> getTypeMap() throws SQLException {
+ return connection.getTypeMap();
+ }
+
+ public void setTypeMap(Map> map) throws SQLException {
+ connection.setTypeMap(map);
+ }
+
+ public void setHoldability(int holdability) throws SQLException {
+ connection.setHoldability(holdability);
+ }
+
+ public int getHoldability() throws SQLException {
+ return connection.getHoldability();
+ }
+
+ public Savepoint setSavepoint() throws SQLException {
+ return connection.setSavepoint();
+ }
+
+ public Savepoint setSavepoint(String name) throws SQLException {
+ return connection.setSavepoint(name);
+ }
+
+ public void rollback(Savepoint savepoint) throws SQLException {
+ connection.rollback();
+ }
+
+ public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+ connection.releaseSavepoint(savepoint);
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ public Clob createClob() throws SQLException {
+ return connection.createClob();
+ }
+
+ public Blob createBlob() throws SQLException {
+ return connection.createBlob();
+ }
+
+ public NClob createNClob() throws SQLException {
+ return connection.createNClob();
+ }
+
+ public SQLXML createSQLXML() throws SQLException {
+ return connection.createSQLXML();
+ }
+
+ public boolean isValid(int timeout) throws SQLException {
+ return connection.isValid(timeout);
+ }
+
+ public void setClientInfo(String name, String value) throws SQLClientInfoException {
+ connection.setClientInfo(name, value);
+ }
+
+ public void setClientInfo(Properties properties) throws SQLClientInfoException {
+ connection.setClientInfo(properties);
+ }
+
+ public String getClientInfo(String name) throws SQLException {
+ return connection.getClientInfo(name);
+ }
+
+ public Properties getClientInfo() throws SQLException {
+ return connection.getClientInfo();
+ }
+
+ public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
+ return connection.createArrayOf(typeName, elements);
+ }
+
+ public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
+ return connection.createStruct(typeName, attributes);
+ }
+
+ @Override
+ public void setSchema(String schema) throws SQLException {
+ connection.setSchema(schema);
+ }
+
+ @Override
+ public String getSchema() throws SQLException {
+ return connection.getSchema();
+ }
+
+ @Override
+ public void abort(Executor executor) throws SQLException {
+ connection.abort(executor);
+ }
+
+ @Override
+ public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
+ connection.setNetworkTimeout(executor, milliseconds);
+ }
+
+ @Override
+ public int getNetworkTimeout() throws SQLException {
+ return connection.getNetworkTimeout();
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return connection.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return connection.isWrapperFor(iface);
+ }
+}
diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java
new file mode 100644
index 0000000..8317172
--- /dev/null
+++ b/src/nl/astraeus/jdbc/Driver.java
@@ -0,0 +1,116 @@
+package nl.astraeus.jdbc;
+
+import nl.astraeus.http.SimpleWebServer;
+import nl.astraeus.jdbc.web.JdbcStatisticsServlet;
+import nl.astraeus.jdbc.web.ResourceServlet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.*;
+import java.util.Enumeration;
+import java.util.Properties;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:54:37 PM
+ */
+public class Driver implements java.sql.Driver {
+ private final static Logger log = LoggerFactory.getLogger(Driver.class);
+
+ final private static String URL_PREFIX = "jdbc:stat:";
+
+ private java.sql.Driver driver = null;
+ private String[] drivers = {
+ "org.postgresql.Driver",
+ "oracle.jdbc.driver.OracleDriver",
+ "com.sybase.jdbc2.jdbc.SybDriver",
+ "net.sourceforge.jtds.jdbc.Driver",
+ "com.microsoft.jdbc.sqlserver.SQLServerDriver",
+ "com.microsoft.sqlserver.jdbc.SQLServerDriver",
+ "weblogic.jdbc.sqlserver.SQLServerDriver",
+ "com.informix.jdbc.IfxDriver",
+ "org.apache.derby.jdbc.ClientDriver",
+ "org.apache.derby.jdbc.EmbeddedDriver",
+ "com.mysql.jdbc.Driver",
+ "org.hsqldb.jdbcDriver",
+ "org.h2.Driver" };
+
+ static {
+ log.debug("Loading driver class " + Driver.class.getName());
+
+ try {
+ DriverManager.registerDriver(new Driver());
+ } catch (SQLException e) {
+ log.error("", e);
+ }
+ }
+
+ public Driver() {
+ for (String dr : drivers) {
+ try {
+ Class.forName(dr);
+ } catch (Throwable e) {
+ log.debug("Can't instantiate driver: " + dr, e);
+ }
+ }
+ }
+
+ private java.sql.Driver findDriver(String url) throws SQLException {
+ Enumeration e = DriverManager.getDrivers();
+
+ while (e.hasMoreElements()) {
+ java.sql.Driver d = (java.sql.Driver) e.nextElement();
+
+ if (d.acceptsURL(url)) {
+ return d;
+ }
+ }
+
+ throw new SQLException("Driver not found: " + url);
+ }
+
+ public Connection connect(String url, Properties info) throws SQLException {
+ url = url.substring(URL_PREFIX.length());
+
+ if (driver == null) {
+ driver = findDriver(url);
+ }
+
+ if (driver != null) {
+ SimpleWebServer server = new SimpleWebServer(18080);
+
+ server.addServlet(new JdbcStatisticsServlet(), "/");
+ server.addServlet(new ResourceServlet(), "/resources/*");
+
+ server.start();
+ }
+
+ return new ConnectionLogger(driver.connect(url, info));
+ }
+
+ public boolean acceptsURL(String url) throws SQLException {
+ return (url != null && url.startsWith(URL_PREFIX));
+ }
+
+ public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
+ return driver.getPropertyInfo(url, info);
+ }
+
+ public int getMajorVersion() {
+ return driver.getMajorVersion();
+ }
+
+ public int getMinorVersion() {
+ return driver.getMinorVersion();
+ }
+
+ public boolean jdbcCompliant() {
+ return driver.jdbcCompliant();
+ }
+
+ @Override
+ public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ return driver.getParentLogger();
+ }
+}
diff --git a/src/nl/astraeus/jdbc/JdbcLogger.java b/src/nl/astraeus/jdbc/JdbcLogger.java
new file mode 100644
index 0000000..f4bc125
--- /dev/null
+++ b/src/nl/astraeus/jdbc/JdbcLogger.java
@@ -0,0 +1,113 @@
+package nl.astraeus.jdbc;
+
+import nl.astraeus.jdbc.util.Util;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * User: riennentjes
+ * Date: Jul 12, 2008
+ * Time: 9:15:21 AM
+ */
+public class JdbcLogger {
+ private final static Logger logger = LoggerFactory.getLogger(JdbcLogger.class);
+
+ private final static JdbcLogger instance = new JdbcLogger();
+
+ public static JdbcLogger get() {
+ return instance;
+ }
+
+ public final static class LogEntry {
+ public QueryType type;
+ public String sql;
+ public long milli;
+ public long nano;
+ public int count;
+ public int hash;
+
+ public LogEntry(int hash, QueryType type, String sql, long milli, long nano) {
+ this.hash = hash;
+ this.type = type;
+ this.sql = sql;
+ this.milli = milli;
+ this.nano = nano;
+ this.count = 1;
+ }
+
+ public void addCount(long milli, long nano) {
+ synchronized (this) {
+ count++;
+ this.milli += milli;
+ this.nano += nano;
+ }
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public String getMilli() {
+ return Util.formatNano(milli*1000000/count);
+ }
+
+ public String getNano() {
+ return Util.formatNano(nano/count);
+ }
+
+ public String getTotal() {
+ return Util.formatNano(nano);
+ }
+
+ public String getSql() {
+ return sql;
+ }
+ }
+
+ private Map queries;
+
+ public JdbcLogger() {
+ queries = new ConcurrentHashMap();
+ }
+
+ public void logEntry(QueryType type, String sql, long milli, long nano) {
+ int hash = sql.hashCode();
+ LogEntry entry = queries.get(hash);
+
+ if (entry == null) {
+ entry = new LogEntry(hash, type, sql, milli, nano);
+ queries.put(hash, entry);
+ } else {
+ entry.addCount(milli, nano);
+ }
+
+ if (queries.size() > 1000) {
+ List toRemove = new LinkedList();
+ List values = new LinkedList(queries.values());
+
+ Collections.sort(values, new Comparator() {
+ @Override
+ public int compare(LogEntry o1, LogEntry o2) {
+ return o1.count - o2.count;
+ }
+ });
+
+ while (queries.size() > 900) {
+ queries.remove(values.remove(0).hash);
+
+ }
+ }
+ }
+
+ public static void log(QueryType type, String sql, long milli, long nano) {
+ instance.logEntry(type, sql, milli, nano);
+ }
+
+ public Collection getEntries() {
+ return queries.values();
+ }
+
+}
diff --git a/src/nl/astraeus/jdbc/PreparedStatementLogger.java b/src/nl/astraeus/jdbc/PreparedStatementLogger.java
new file mode 100644
index 0000000..98aefc7
--- /dev/null
+++ b/src/nl/astraeus/jdbc/PreparedStatementLogger.java
@@ -0,0 +1,577 @@
+package nl.astraeus.jdbc;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.*;
+import java.util.Calendar;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 7:47:57 PM
+ */
+public class PreparedStatementLogger implements PreparedStatement {
+ private final static Logger log = LoggerFactory.getLogger(PreparedStatementLogger.class);
+
+ private PreparedStatement statement;
+
+ private String sql;
+ private QueryType type;
+ private long milli;
+ private long nano;
+
+ //private ArrayList parameters;
+
+ public PreparedStatementLogger(PreparedStatement statement) {
+ this.statement = statement;
+ this.sql = "";
+ this.type = QueryType.UNKNOWN;
+ }
+
+ private void clearTime() {
+ milli = System.currentTimeMillis();
+ nano = System.nanoTime();
+ }
+
+ private void log(QueryType type, String sql) {
+ long m = System.currentTimeMillis() - milli;
+ long n = System.nanoTime() - nano;
+
+ JdbcLogger.log(type, sql, m, n);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, resultSetType, resultSetConcurrency);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, autoGeneratedKeys);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int[] columnIndexes) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, columnIndexes);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, String[] columnNames) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, columnNames);
+ }
+
+ public boolean execute() throws SQLException {
+ clearTime();
+
+ boolean result = statement.execute();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public ResultSet executeQuery() throws SQLException {
+ clearTime();
+
+ ResultSet result = statement.executeQuery();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate() throws SQLException {
+ clearTime();
+
+ int result = statement.executeUpdate();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public ResultSet executeQuery(String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ ResultSet result = statement.executeQuery(sql);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, autoGeneratedKeys);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, int columnIndexes[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, columnIndexes);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, String columnNames[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, columnNames);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, autoGeneratedKeys);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, int columnIndexes[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, columnIndexes);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, String columnNames[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, columnNames);
+
+ log(type, sql);
+
+ return result;
+ }
+
+
+ public void setNull(int parameterIndex, int sqlType) throws SQLException {
+ statement.setNull(parameterIndex, sqlType);
+ }
+
+ public void setBoolean(int parameterIndex, boolean x) throws SQLException {
+ statement.setBoolean(parameterIndex, x);
+ }
+
+ public void setByte(int parameterIndex, byte x) throws SQLException {
+ statement.setByte(parameterIndex, x);
+ }
+
+ public void setShort(int parameterIndex, short x) throws SQLException {
+ statement.setShort(parameterIndex, x);
+ }
+
+ public void setInt(int parameterIndex, int x) throws SQLException {
+ statement.setInt(parameterIndex, x);
+ }
+
+ public void setLong(int parameterIndex, long x) throws SQLException {
+ statement.setLong(parameterIndex, x);
+ }
+
+ public void setFloat(int parameterIndex, float x) throws SQLException {
+ statement.setFloat(parameterIndex, x);
+ }
+
+ public void setDouble(int parameterIndex, double x) throws SQLException {
+ statement.setDouble(parameterIndex, x);
+ }
+
+ public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
+ statement.setBigDecimal(parameterIndex, x);
+ }
+
+ public void setString(int parameterIndex, String x) throws SQLException {
+ statement.setString(parameterIndex, x);
+ }
+
+ public void setBytes(int parameterIndex, byte x[]) throws SQLException {
+ statement.setBytes(parameterIndex, x);
+ }
+
+ public void setDate(int parameterIndex, Date x) throws SQLException {
+ statement.setDate(parameterIndex, x);
+ }
+
+ public void setTime(int parameterIndex, Time x) throws SQLException {
+ statement.setTime(parameterIndex, x);
+ }
+
+ public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
+ statement.setTimestamp(parameterIndex, x);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x, length);
+ }
+
+ public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setUnicodeStream(parameterIndex, x, length);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x, length);
+ }
+
+ public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
+ statement.setObject(parameterIndex, x, targetSqlType);
+ }
+
+ public void setObject(int parameterIndex, Object x) throws SQLException {
+ statement.setObject(parameterIndex, x);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ public void setRef(int parameterIndex, Ref x) throws SQLException {
+ statement.setRef(parameterIndex, x);
+ }
+
+ public void setBlob(int parameterIndex, Blob x) throws SQLException {
+ statement.setBlob(parameterIndex, x);
+ }
+
+ public void setClob(int parameterIndex, Clob x) throws SQLException {
+ statement.setClob(parameterIndex, x);
+ }
+
+ public void setArray(int parameterIndex, Array x) throws SQLException {
+ statement.setArray(parameterIndex, x);
+ }
+
+ public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
+ statement.setDate(parameterIndex, x, cal);
+ }
+
+ public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
+ statement.setTime(parameterIndex, x, cal);
+ }
+
+ public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
+ statement.setTimestamp(parameterIndex, x, cal);
+ }
+
+ public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
+ statement.setNull(parameterIndex, sqlType, typeName);
+ }
+
+ public void setURL(int parameterIndex, URL x) throws SQLException {
+ statement.setURL(parameterIndex, x);
+ }
+
+ public void setRowId(int parameterIndex, RowId x) throws SQLException {
+ statement.setRowId(parameterIndex, x);
+ }
+
+ public void setNString(int parameterIndex, String value) throws SQLException {
+ statement.setNString(parameterIndex, value);
+ }
+
+ public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
+ statement.setNCharacterStream(parameterIndex, value, length);
+ }
+
+ public void setNClob(int parameterIndex, NClob value) throws SQLException {
+ statement.setNClob(parameterIndex, value);
+ }
+
+ public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setClob(parameterIndex, reader, length);
+ }
+
+ public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
+ statement.setBlob(parameterIndex, inputStream, length);
+ }
+
+ public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setNClob(parameterIndex, reader, length);
+ }
+
+ public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
+ statement.setSQLXML(parameterIndex, xmlObject);
+ }
+
+ public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException {
+ statement.setObject(parameterIndex, x, targetSqlType, scaleOrLength);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x, length);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x, length);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader);
+ }
+
+ public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
+ statement.setNCharacterStream(parameterIndex, value);
+ }
+
+ public void setClob(int parameterIndex, Reader reader) throws SQLException {
+ statement.setClob(parameterIndex, reader);
+ }
+
+ public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
+ statement.setBlob(parameterIndex, inputStream);
+ }
+
+ public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+ statement.setNClob(parameterIndex, reader);
+ }
+
+
+ public void close() throws SQLException {
+ sql = "";
+ type = QueryType.UNKNOWN;
+ milli = 0;
+ nano = 0;
+
+ statement.close();
+ }
+
+ public ResultSetMetaData getMetaData() throws SQLException {
+ return statement.getMetaData();
+ }
+
+ public void clearParameters() throws SQLException {
+ statement.clearParameters();
+ }
+
+ public ParameterMetaData getParameterMetaData() throws SQLException {
+ return statement.getParameterMetaData();
+ }
+
+ public void addBatch() throws SQLException {
+ statement.addBatch();
+ }
+
+ public int getMaxFieldSize() throws SQLException {
+ return statement.getMaxFieldSize();
+ }
+
+ public void setMaxFieldSize(int max) throws SQLException {
+ statement.setMaxFieldSize(max);
+ }
+
+ public int getMaxRows() throws SQLException {
+ return statement.getMaxRows();
+ }
+
+ public void setMaxRows(int max) throws SQLException {
+ statement.setMaxRows(max);
+ }
+
+ public void setEscapeProcessing(boolean enable) throws SQLException {
+ statement.setEscapeProcessing(enable);
+ }
+
+ public int getQueryTimeout() throws SQLException {
+ return statement.getQueryTimeout();
+ }
+
+ public void setQueryTimeout(int seconds) throws SQLException {
+ statement.setQueryTimeout(seconds);
+ }
+
+ public void cancel() throws SQLException {
+ statement.cancel();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return statement.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ statement.clearWarnings();
+ }
+
+ public void setCursorName(String name) throws SQLException {
+ statement.setCursorName(name);
+ }
+
+ public boolean execute(String sql) throws SQLException {
+ return statement.execute(sql);
+ }
+
+ public ResultSet getResultSet() throws SQLException {
+ return statement.getResultSet();
+ }
+
+ public int getUpdateCount() throws SQLException {
+ return statement.getUpdateCount();
+ }
+
+ public boolean getMoreResults() throws SQLException {
+ return statement.getMoreResults();
+ }
+
+ public void setFetchDirection(int direction) throws SQLException {
+ statement.setFetchDirection(direction);
+ }
+
+ public int getFetchDirection() throws SQLException {
+ return statement.getFetchDirection();
+ }
+
+ public void setFetchSize(int rows) throws SQLException {
+ statement.setFetchSize(rows);
+ }
+
+ public int getFetchSize() throws SQLException {
+ return statement.getFetchSize();
+ }
+
+ public int getResultSetConcurrency() throws SQLException {
+ return statement.getResultSetConcurrency();
+ }
+
+ public int getResultSetType() throws SQLException {
+ return statement.getResultSetType();
+ }
+
+ public void addBatch(String sql) throws SQLException {
+ statement.addBatch(sql);
+ }
+
+ public void clearBatch() throws SQLException {
+ statement.clearBatch();
+ }
+
+ public int[] executeBatch() throws SQLException {
+ return statement.executeBatch();
+ }
+
+ public Connection getConnection() throws SQLException {
+ return statement.getConnection();
+ }
+
+ public boolean getMoreResults(int current) throws SQLException {
+ return statement.getMoreResults(current);
+ }
+
+ public ResultSet getGeneratedKeys() throws SQLException {
+ return statement.getGeneratedKeys();
+ }
+
+ public int getResultSetHoldability() throws SQLException {
+ return statement.getResultSetHoldability();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return statement.isClosed();
+ }
+
+ public void setPoolable(boolean poolable) throws SQLException {
+ statement.setPoolable(poolable);
+ }
+
+ public boolean isPoolable() throws SQLException {
+ return statement.isPoolable();
+ }
+
+ @Override
+ public void closeOnCompletion() throws SQLException {
+ statement.closeOnCompletion();;
+ }
+
+ @Override
+ public boolean isCloseOnCompletion() throws SQLException {
+ return statement.isCloseOnCompletion();
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return statement.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return statement.isWrapperFor(iface);
+ }
+}
diff --git a/src/nl/astraeus/jdbc/QueryType.java b/src/nl/astraeus/jdbc/QueryType.java
new file mode 100644
index 0000000..744fbfc
--- /dev/null
+++ b/src/nl/astraeus/jdbc/QueryType.java
@@ -0,0 +1,24 @@
+package nl.astraeus.jdbc;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:32:49 PM
+ */
+public enum QueryType {
+ PLAIN("plain"),
+ PREPARED("prepared"),
+ CALLABLE("callable"),
+ UNKNOWN("unknown");
+
+ private String description;
+
+ QueryType(String description) {
+ this.description = description;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+}
diff --git a/src/nl/astraeus/jdbc/example/JdbcStatisticsExample.java b/src/nl/astraeus/jdbc/example/JdbcStatisticsExample.java
new file mode 100644
index 0000000..07aac40
--- /dev/null
+++ b/src/nl/astraeus/jdbc/example/JdbcStatisticsExample.java
@@ -0,0 +1,68 @@
+package nl.astraeus.jdbc.example;
+
+import java.sql.*;
+
+/**
+ * User: rnentjes
+ * Date: 4/12/12
+ * Time: 7:32 PM
+ */
+public class JdbcStatisticsExample {
+
+
+ public static void main(String [] args) throws Exception {
+ Class.forName("org.h2.Driver");
+ Class.forName("nl.astraeus.jdbc.Driver");
+
+ new JdbcStatisticsExample();
+ }
+
+ public JdbcStatisticsExample() throws Exception {
+ Connection conn = DriverManager.getConnection("jdbc:stat:jdbc:h2:mem:test");
+
+ Statement statement = null;
+
+ statement = conn.createStatement();
+ statement.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))");
+ statement.close();
+
+ boolean running = true;
+ int count = 1;
+ PreparedStatement ps = null;
+
+ while (running) {
+ Thread.sleep(10);
+
+ String TableName = "TEST"+(System.nanoTime() % 1000);
+
+ try {
+ ps = conn.prepareStatement("SELECT COUNT(*) FROM "+TableName);
+ ResultSet rs = ps.executeQuery();
+ } catch (SQLException e) {
+ statement = conn.createStatement();
+ statement.execute("CREATE TABLE "+TableName+" (ID INT PRIMARY KEY, NAME VARCHAR(255))");
+ statement.close();
+ } finally {
+ if (ps!=null) {
+ ps.close();
+ }
+ }
+
+ ps = conn.prepareStatement("INSERT INTO "+TableName+" VALUES (?, ?)");
+
+ ps.setInt(1, count++);
+ ps.setString(2, "String "+System.currentTimeMillis());
+
+ ps.execute();
+ ps.close();
+
+ Thread.sleep(10);
+
+ ps = conn.prepareStatement("SELECT * FROM "+TableName);
+ ResultSet rs = ps.executeQuery();
+ statement.close();
+ }
+
+ conn.close();
+ }
+}
diff --git a/src/nl/astraeus/jdbc/util/IOUtils.java b/src/nl/astraeus/jdbc/util/IOUtils.java
new file mode 100644
index 0000000..ce95d9d
--- /dev/null
+++ b/src/nl/astraeus/jdbc/util/IOUtils.java
@@ -0,0 +1,38 @@
+package nl.astraeus.jdbc.util;
+
+import java.io.*;
+
+/**
+ * User: rnentjes
+ * Date: 4/9/12
+ * Time: 2:33 PM
+ */
+public class IOUtils {
+
+ public static String toString(InputStream in) throws IOException {
+ assert in != null;
+
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ StringBuilder buffer = new StringBuilder();
+
+ while(reader.ready()) {
+ buffer.append(reader.readLine());
+ buffer.append("\n");
+ }
+
+ return buffer.toString();
+ } finally {
+ in.close();
+ }
+ }
+
+ public static void copy(InputStream in, OutputStream out) throws IOException {
+ byte [] buffer = new byte[1<<16];
+ int bytes;
+
+ while((bytes = in.read(buffer)) > 0) {
+ out.write(buffer, 0, bytes);
+ }
+ }
+}
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..275077f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README b/README
deleted file mode 100644
index 734abaf..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-This file was created by IntelliJ IDEA 11.1.1 for binding GitHub repository
\ No newline at end of file
diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml
new file mode 100644
index 0000000..ca90a9b
--- /dev/null
+++ b/Simple-jdbc-statistics.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/h2-1.3.166.jar b/lib/h2-1.3.166.jar
new file mode 100644
index 0000000..4985063
--- /dev/null
+++ b/lib/h2-1.3.166.jar
Binary files differ
diff --git a/lib/servlet-api-2.5.jar b/lib/servlet-api-2.5.jar
new file mode 100644
index 0000000..20b5755
--- /dev/null
+++ b/lib/servlet-api-2.5.jar
Binary files differ
diff --git a/lib/slf4j-api-1.6.4.jar b/lib/slf4j-api-1.6.4.jar
new file mode 100644
index 0000000..4d23f41
--- /dev/null
+++ b/lib/slf4j-api-1.6.4.jar
Binary files differ
diff --git a/lib/slf4j-simple-1.6.4.jar b/lib/slf4j-simple-1.6.4.jar
new file mode 100644
index 0000000..3d1b8d9
--- /dev/null
+++ b/lib/slf4j-simple-1.6.4.jar
Binary files differ
diff --git a/lib/ssr-0.1.jar b/lib/ssr-0.1.jar
new file mode 100644
index 0000000..65dfcf4
--- /dev/null
+++ b/lib/ssr-0.1.jar
Binary files differ
diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar
new file mode 100644
index 0000000..db63792
--- /dev/null
+++ b/lib/vst-0.4.jar
Binary files differ
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..ac2dbe1
--- /dev/null
+++ b/readme.md
@@ -0,0 +1 @@
+A simple wrapper around jdbc drivers what will show current jdbc stats of the running queries on a simple web page on port 18080.
\ No newline at end of file
diff --git a/src/nl/astraeus/jdbc/ConnectionLogger.java b/src/nl/astraeus/jdbc/ConnectionLogger.java
new file mode 100644
index 0000000..c3e243f
--- /dev/null
+++ b/src/nl/astraeus/jdbc/ConnectionLogger.java
@@ -0,0 +1,279 @@
+package nl.astraeus.jdbc;
+
+import java.sql.*;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:12:34 PM
+ */
+public class ConnectionLogger implements Connection {
+ private Connection connection;
+
+ private long milli;
+ private long nano;
+ private String lastSql;
+
+ public ConnectionLogger(Connection connection) {
+ this.connection = connection;
+ this.lastSql = "";
+ }
+
+ private void clearTime() {
+ milli = System.currentTimeMillis();
+ nano = System.nanoTime();
+ }
+
+ private void log(String sql) {
+ long m = System.currentTimeMillis() - milli;
+ long n = System.nanoTime() - nano;
+
+ JdbcLogger.log(QueryType.UNKNOWN, sql, m, n);
+ }
+
+ public void commit() throws SQLException {
+ clearTime();
+
+ connection.commit();
+
+ log("commit");
+ }
+
+ public void rollback() throws SQLException {
+ clearTime();
+
+ connection.rollback();
+
+ log("rollback");
+ }
+
+ public void close() throws SQLException {
+ clearTime();
+
+ connection.close();
+
+ log("close");
+ }
+
+ public PreparedStatement prepareStatement(String sql) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, autoGeneratedKeys);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int columnIndexes[]) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, columnIndexes);
+ }
+
+ public PreparedStatement prepareStatement(String sql, String columnNames[]) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, columnNames);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ public Statement createStatement() throws SQLException {
+ return connection.createStatement();
+ }
+
+ public CallableStatement prepareCall(String sql) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql);
+ }
+
+ public String nativeSQL(String sql) throws SQLException {
+ lastSql = sql;
+ return connection.nativeSQL(sql);
+ }
+
+ public void setAutoCommit(boolean autoCommit) throws SQLException {
+ connection.setAutoCommit(autoCommit);
+ }
+
+ public boolean getAutoCommit() throws SQLException {
+ return connection.getAutoCommit();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return connection.isClosed();
+ }
+
+ public DatabaseMetaData getMetaData() throws SQLException {
+ return connection.getMetaData();
+ }
+
+ public void setReadOnly(boolean readOnly) throws SQLException {
+ connection.setReadOnly(readOnly);
+ }
+
+ public boolean isReadOnly() throws SQLException {
+ return connection.isReadOnly();
+ }
+
+ public void setCatalog(String catalog) throws SQLException {
+ connection.setCatalog(catalog);
+ }
+
+ public String getCatalog() throws SQLException {
+ return connection.getCatalog();
+ }
+
+ public void setTransactionIsolation(int level) throws SQLException {
+ connection.setTransactionIsolation(level);
+ }
+
+ public int getTransactionIsolation() throws SQLException {
+ return connection.getTransactionIsolation();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return connection.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ connection.clearWarnings();
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency);
+ }
+
+ public Map> getTypeMap() throws SQLException {
+ return connection.getTypeMap();
+ }
+
+ public void setTypeMap(Map> map) throws SQLException {
+ connection.setTypeMap(map);
+ }
+
+ public void setHoldability(int holdability) throws SQLException {
+ connection.setHoldability(holdability);
+ }
+
+ public int getHoldability() throws SQLException {
+ return connection.getHoldability();
+ }
+
+ public Savepoint setSavepoint() throws SQLException {
+ return connection.setSavepoint();
+ }
+
+ public Savepoint setSavepoint(String name) throws SQLException {
+ return connection.setSavepoint(name);
+ }
+
+ public void rollback(Savepoint savepoint) throws SQLException {
+ connection.rollback();
+ }
+
+ public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+ connection.releaseSavepoint(savepoint);
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ public Clob createClob() throws SQLException {
+ return connection.createClob();
+ }
+
+ public Blob createBlob() throws SQLException {
+ return connection.createBlob();
+ }
+
+ public NClob createNClob() throws SQLException {
+ return connection.createNClob();
+ }
+
+ public SQLXML createSQLXML() throws SQLException {
+ return connection.createSQLXML();
+ }
+
+ public boolean isValid(int timeout) throws SQLException {
+ return connection.isValid(timeout);
+ }
+
+ public void setClientInfo(String name, String value) throws SQLClientInfoException {
+ connection.setClientInfo(name, value);
+ }
+
+ public void setClientInfo(Properties properties) throws SQLClientInfoException {
+ connection.setClientInfo(properties);
+ }
+
+ public String getClientInfo(String name) throws SQLException {
+ return connection.getClientInfo(name);
+ }
+
+ public Properties getClientInfo() throws SQLException {
+ return connection.getClientInfo();
+ }
+
+ public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
+ return connection.createArrayOf(typeName, elements);
+ }
+
+ public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
+ return connection.createStruct(typeName, attributes);
+ }
+
+ @Override
+ public void setSchema(String schema) throws SQLException {
+ connection.setSchema(schema);
+ }
+
+ @Override
+ public String getSchema() throws SQLException {
+ return connection.getSchema();
+ }
+
+ @Override
+ public void abort(Executor executor) throws SQLException {
+ connection.abort(executor);
+ }
+
+ @Override
+ public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
+ connection.setNetworkTimeout(executor, milliseconds);
+ }
+
+ @Override
+ public int getNetworkTimeout() throws SQLException {
+ return connection.getNetworkTimeout();
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return connection.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return connection.isWrapperFor(iface);
+ }
+}
diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java
new file mode 100644
index 0000000..8317172
--- /dev/null
+++ b/src/nl/astraeus/jdbc/Driver.java
@@ -0,0 +1,116 @@
+package nl.astraeus.jdbc;
+
+import nl.astraeus.http.SimpleWebServer;
+import nl.astraeus.jdbc.web.JdbcStatisticsServlet;
+import nl.astraeus.jdbc.web.ResourceServlet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.*;
+import java.util.Enumeration;
+import java.util.Properties;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:54:37 PM
+ */
+public class Driver implements java.sql.Driver {
+ private final static Logger log = LoggerFactory.getLogger(Driver.class);
+
+ final private static String URL_PREFIX = "jdbc:stat:";
+
+ private java.sql.Driver driver = null;
+ private String[] drivers = {
+ "org.postgresql.Driver",
+ "oracle.jdbc.driver.OracleDriver",
+ "com.sybase.jdbc2.jdbc.SybDriver",
+ "net.sourceforge.jtds.jdbc.Driver",
+ "com.microsoft.jdbc.sqlserver.SQLServerDriver",
+ "com.microsoft.sqlserver.jdbc.SQLServerDriver",
+ "weblogic.jdbc.sqlserver.SQLServerDriver",
+ "com.informix.jdbc.IfxDriver",
+ "org.apache.derby.jdbc.ClientDriver",
+ "org.apache.derby.jdbc.EmbeddedDriver",
+ "com.mysql.jdbc.Driver",
+ "org.hsqldb.jdbcDriver",
+ "org.h2.Driver" };
+
+ static {
+ log.debug("Loading driver class " + Driver.class.getName());
+
+ try {
+ DriverManager.registerDriver(new Driver());
+ } catch (SQLException e) {
+ log.error("", e);
+ }
+ }
+
+ public Driver() {
+ for (String dr : drivers) {
+ try {
+ Class.forName(dr);
+ } catch (Throwable e) {
+ log.debug("Can't instantiate driver: " + dr, e);
+ }
+ }
+ }
+
+ private java.sql.Driver findDriver(String url) throws SQLException {
+ Enumeration e = DriverManager.getDrivers();
+
+ while (e.hasMoreElements()) {
+ java.sql.Driver d = (java.sql.Driver) e.nextElement();
+
+ if (d.acceptsURL(url)) {
+ return d;
+ }
+ }
+
+ throw new SQLException("Driver not found: " + url);
+ }
+
+ public Connection connect(String url, Properties info) throws SQLException {
+ url = url.substring(URL_PREFIX.length());
+
+ if (driver == null) {
+ driver = findDriver(url);
+ }
+
+ if (driver != null) {
+ SimpleWebServer server = new SimpleWebServer(18080);
+
+ server.addServlet(new JdbcStatisticsServlet(), "/");
+ server.addServlet(new ResourceServlet(), "/resources/*");
+
+ server.start();
+ }
+
+ return new ConnectionLogger(driver.connect(url, info));
+ }
+
+ public boolean acceptsURL(String url) throws SQLException {
+ return (url != null && url.startsWith(URL_PREFIX));
+ }
+
+ public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
+ return driver.getPropertyInfo(url, info);
+ }
+
+ public int getMajorVersion() {
+ return driver.getMajorVersion();
+ }
+
+ public int getMinorVersion() {
+ return driver.getMinorVersion();
+ }
+
+ public boolean jdbcCompliant() {
+ return driver.jdbcCompliant();
+ }
+
+ @Override
+ public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ return driver.getParentLogger();
+ }
+}
diff --git a/src/nl/astraeus/jdbc/JdbcLogger.java b/src/nl/astraeus/jdbc/JdbcLogger.java
new file mode 100644
index 0000000..f4bc125
--- /dev/null
+++ b/src/nl/astraeus/jdbc/JdbcLogger.java
@@ -0,0 +1,113 @@
+package nl.astraeus.jdbc;
+
+import nl.astraeus.jdbc.util.Util;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * User: riennentjes
+ * Date: Jul 12, 2008
+ * Time: 9:15:21 AM
+ */
+public class JdbcLogger {
+ private final static Logger logger = LoggerFactory.getLogger(JdbcLogger.class);
+
+ private final static JdbcLogger instance = new JdbcLogger();
+
+ public static JdbcLogger get() {
+ return instance;
+ }
+
+ public final static class LogEntry {
+ public QueryType type;
+ public String sql;
+ public long milli;
+ public long nano;
+ public int count;
+ public int hash;
+
+ public LogEntry(int hash, QueryType type, String sql, long milli, long nano) {
+ this.hash = hash;
+ this.type = type;
+ this.sql = sql;
+ this.milli = milli;
+ this.nano = nano;
+ this.count = 1;
+ }
+
+ public void addCount(long milli, long nano) {
+ synchronized (this) {
+ count++;
+ this.milli += milli;
+ this.nano += nano;
+ }
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public String getMilli() {
+ return Util.formatNano(milli*1000000/count);
+ }
+
+ public String getNano() {
+ return Util.formatNano(nano/count);
+ }
+
+ public String getTotal() {
+ return Util.formatNano(nano);
+ }
+
+ public String getSql() {
+ return sql;
+ }
+ }
+
+ private Map queries;
+
+ public JdbcLogger() {
+ queries = new ConcurrentHashMap();
+ }
+
+ public void logEntry(QueryType type, String sql, long milli, long nano) {
+ int hash = sql.hashCode();
+ LogEntry entry = queries.get(hash);
+
+ if (entry == null) {
+ entry = new LogEntry(hash, type, sql, milli, nano);
+ queries.put(hash, entry);
+ } else {
+ entry.addCount(milli, nano);
+ }
+
+ if (queries.size() > 1000) {
+ List toRemove = new LinkedList();
+ List values = new LinkedList(queries.values());
+
+ Collections.sort(values, new Comparator() {
+ @Override
+ public int compare(LogEntry o1, LogEntry o2) {
+ return o1.count - o2.count;
+ }
+ });
+
+ while (queries.size() > 900) {
+ queries.remove(values.remove(0).hash);
+
+ }
+ }
+ }
+
+ public static void log(QueryType type, String sql, long milli, long nano) {
+ instance.logEntry(type, sql, milli, nano);
+ }
+
+ public Collection getEntries() {
+ return queries.values();
+ }
+
+}
diff --git a/src/nl/astraeus/jdbc/PreparedStatementLogger.java b/src/nl/astraeus/jdbc/PreparedStatementLogger.java
new file mode 100644
index 0000000..98aefc7
--- /dev/null
+++ b/src/nl/astraeus/jdbc/PreparedStatementLogger.java
@@ -0,0 +1,577 @@
+package nl.astraeus.jdbc;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.*;
+import java.util.Calendar;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 7:47:57 PM
+ */
+public class PreparedStatementLogger implements PreparedStatement {
+ private final static Logger log = LoggerFactory.getLogger(PreparedStatementLogger.class);
+
+ private PreparedStatement statement;
+
+ private String sql;
+ private QueryType type;
+ private long milli;
+ private long nano;
+
+ //private ArrayList parameters;
+
+ public PreparedStatementLogger(PreparedStatement statement) {
+ this.statement = statement;
+ this.sql = "";
+ this.type = QueryType.UNKNOWN;
+ }
+
+ private void clearTime() {
+ milli = System.currentTimeMillis();
+ nano = System.nanoTime();
+ }
+
+ private void log(QueryType type, String sql) {
+ long m = System.currentTimeMillis() - milli;
+ long n = System.nanoTime() - nano;
+
+ JdbcLogger.log(type, sql, m, n);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, resultSetType, resultSetConcurrency);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, autoGeneratedKeys);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int[] columnIndexes) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, columnIndexes);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, String[] columnNames) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, columnNames);
+ }
+
+ public boolean execute() throws SQLException {
+ clearTime();
+
+ boolean result = statement.execute();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public ResultSet executeQuery() throws SQLException {
+ clearTime();
+
+ ResultSet result = statement.executeQuery();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate() throws SQLException {
+ clearTime();
+
+ int result = statement.executeUpdate();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public ResultSet executeQuery(String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ ResultSet result = statement.executeQuery(sql);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, autoGeneratedKeys);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, int columnIndexes[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, columnIndexes);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, String columnNames[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, columnNames);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, autoGeneratedKeys);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, int columnIndexes[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, columnIndexes);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, String columnNames[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, columnNames);
+
+ log(type, sql);
+
+ return result;
+ }
+
+
+ public void setNull(int parameterIndex, int sqlType) throws SQLException {
+ statement.setNull(parameterIndex, sqlType);
+ }
+
+ public void setBoolean(int parameterIndex, boolean x) throws SQLException {
+ statement.setBoolean(parameterIndex, x);
+ }
+
+ public void setByte(int parameterIndex, byte x) throws SQLException {
+ statement.setByte(parameterIndex, x);
+ }
+
+ public void setShort(int parameterIndex, short x) throws SQLException {
+ statement.setShort(parameterIndex, x);
+ }
+
+ public void setInt(int parameterIndex, int x) throws SQLException {
+ statement.setInt(parameterIndex, x);
+ }
+
+ public void setLong(int parameterIndex, long x) throws SQLException {
+ statement.setLong(parameterIndex, x);
+ }
+
+ public void setFloat(int parameterIndex, float x) throws SQLException {
+ statement.setFloat(parameterIndex, x);
+ }
+
+ public void setDouble(int parameterIndex, double x) throws SQLException {
+ statement.setDouble(parameterIndex, x);
+ }
+
+ public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
+ statement.setBigDecimal(parameterIndex, x);
+ }
+
+ public void setString(int parameterIndex, String x) throws SQLException {
+ statement.setString(parameterIndex, x);
+ }
+
+ public void setBytes(int parameterIndex, byte x[]) throws SQLException {
+ statement.setBytes(parameterIndex, x);
+ }
+
+ public void setDate(int parameterIndex, Date x) throws SQLException {
+ statement.setDate(parameterIndex, x);
+ }
+
+ public void setTime(int parameterIndex, Time x) throws SQLException {
+ statement.setTime(parameterIndex, x);
+ }
+
+ public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
+ statement.setTimestamp(parameterIndex, x);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x, length);
+ }
+
+ public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setUnicodeStream(parameterIndex, x, length);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x, length);
+ }
+
+ public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
+ statement.setObject(parameterIndex, x, targetSqlType);
+ }
+
+ public void setObject(int parameterIndex, Object x) throws SQLException {
+ statement.setObject(parameterIndex, x);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ public void setRef(int parameterIndex, Ref x) throws SQLException {
+ statement.setRef(parameterIndex, x);
+ }
+
+ public void setBlob(int parameterIndex, Blob x) throws SQLException {
+ statement.setBlob(parameterIndex, x);
+ }
+
+ public void setClob(int parameterIndex, Clob x) throws SQLException {
+ statement.setClob(parameterIndex, x);
+ }
+
+ public void setArray(int parameterIndex, Array x) throws SQLException {
+ statement.setArray(parameterIndex, x);
+ }
+
+ public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
+ statement.setDate(parameterIndex, x, cal);
+ }
+
+ public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
+ statement.setTime(parameterIndex, x, cal);
+ }
+
+ public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
+ statement.setTimestamp(parameterIndex, x, cal);
+ }
+
+ public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
+ statement.setNull(parameterIndex, sqlType, typeName);
+ }
+
+ public void setURL(int parameterIndex, URL x) throws SQLException {
+ statement.setURL(parameterIndex, x);
+ }
+
+ public void setRowId(int parameterIndex, RowId x) throws SQLException {
+ statement.setRowId(parameterIndex, x);
+ }
+
+ public void setNString(int parameterIndex, String value) throws SQLException {
+ statement.setNString(parameterIndex, value);
+ }
+
+ public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
+ statement.setNCharacterStream(parameterIndex, value, length);
+ }
+
+ public void setNClob(int parameterIndex, NClob value) throws SQLException {
+ statement.setNClob(parameterIndex, value);
+ }
+
+ public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setClob(parameterIndex, reader, length);
+ }
+
+ public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
+ statement.setBlob(parameterIndex, inputStream, length);
+ }
+
+ public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setNClob(parameterIndex, reader, length);
+ }
+
+ public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
+ statement.setSQLXML(parameterIndex, xmlObject);
+ }
+
+ public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException {
+ statement.setObject(parameterIndex, x, targetSqlType, scaleOrLength);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x, length);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x, length);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader);
+ }
+
+ public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
+ statement.setNCharacterStream(parameterIndex, value);
+ }
+
+ public void setClob(int parameterIndex, Reader reader) throws SQLException {
+ statement.setClob(parameterIndex, reader);
+ }
+
+ public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
+ statement.setBlob(parameterIndex, inputStream);
+ }
+
+ public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+ statement.setNClob(parameterIndex, reader);
+ }
+
+
+ public void close() throws SQLException {
+ sql = "";
+ type = QueryType.UNKNOWN;
+ milli = 0;
+ nano = 0;
+
+ statement.close();
+ }
+
+ public ResultSetMetaData getMetaData() throws SQLException {
+ return statement.getMetaData();
+ }
+
+ public void clearParameters() throws SQLException {
+ statement.clearParameters();
+ }
+
+ public ParameterMetaData getParameterMetaData() throws SQLException {
+ return statement.getParameterMetaData();
+ }
+
+ public void addBatch() throws SQLException {
+ statement.addBatch();
+ }
+
+ public int getMaxFieldSize() throws SQLException {
+ return statement.getMaxFieldSize();
+ }
+
+ public void setMaxFieldSize(int max) throws SQLException {
+ statement.setMaxFieldSize(max);
+ }
+
+ public int getMaxRows() throws SQLException {
+ return statement.getMaxRows();
+ }
+
+ public void setMaxRows(int max) throws SQLException {
+ statement.setMaxRows(max);
+ }
+
+ public void setEscapeProcessing(boolean enable) throws SQLException {
+ statement.setEscapeProcessing(enable);
+ }
+
+ public int getQueryTimeout() throws SQLException {
+ return statement.getQueryTimeout();
+ }
+
+ public void setQueryTimeout(int seconds) throws SQLException {
+ statement.setQueryTimeout(seconds);
+ }
+
+ public void cancel() throws SQLException {
+ statement.cancel();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return statement.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ statement.clearWarnings();
+ }
+
+ public void setCursorName(String name) throws SQLException {
+ statement.setCursorName(name);
+ }
+
+ public boolean execute(String sql) throws SQLException {
+ return statement.execute(sql);
+ }
+
+ public ResultSet getResultSet() throws SQLException {
+ return statement.getResultSet();
+ }
+
+ public int getUpdateCount() throws SQLException {
+ return statement.getUpdateCount();
+ }
+
+ public boolean getMoreResults() throws SQLException {
+ return statement.getMoreResults();
+ }
+
+ public void setFetchDirection(int direction) throws SQLException {
+ statement.setFetchDirection(direction);
+ }
+
+ public int getFetchDirection() throws SQLException {
+ return statement.getFetchDirection();
+ }
+
+ public void setFetchSize(int rows) throws SQLException {
+ statement.setFetchSize(rows);
+ }
+
+ public int getFetchSize() throws SQLException {
+ return statement.getFetchSize();
+ }
+
+ public int getResultSetConcurrency() throws SQLException {
+ return statement.getResultSetConcurrency();
+ }
+
+ public int getResultSetType() throws SQLException {
+ return statement.getResultSetType();
+ }
+
+ public void addBatch(String sql) throws SQLException {
+ statement.addBatch(sql);
+ }
+
+ public void clearBatch() throws SQLException {
+ statement.clearBatch();
+ }
+
+ public int[] executeBatch() throws SQLException {
+ return statement.executeBatch();
+ }
+
+ public Connection getConnection() throws SQLException {
+ return statement.getConnection();
+ }
+
+ public boolean getMoreResults(int current) throws SQLException {
+ return statement.getMoreResults(current);
+ }
+
+ public ResultSet getGeneratedKeys() throws SQLException {
+ return statement.getGeneratedKeys();
+ }
+
+ public int getResultSetHoldability() throws SQLException {
+ return statement.getResultSetHoldability();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return statement.isClosed();
+ }
+
+ public void setPoolable(boolean poolable) throws SQLException {
+ statement.setPoolable(poolable);
+ }
+
+ public boolean isPoolable() throws SQLException {
+ return statement.isPoolable();
+ }
+
+ @Override
+ public void closeOnCompletion() throws SQLException {
+ statement.closeOnCompletion();;
+ }
+
+ @Override
+ public boolean isCloseOnCompletion() throws SQLException {
+ return statement.isCloseOnCompletion();
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return statement.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return statement.isWrapperFor(iface);
+ }
+}
diff --git a/src/nl/astraeus/jdbc/QueryType.java b/src/nl/astraeus/jdbc/QueryType.java
new file mode 100644
index 0000000..744fbfc
--- /dev/null
+++ b/src/nl/astraeus/jdbc/QueryType.java
@@ -0,0 +1,24 @@
+package nl.astraeus.jdbc;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:32:49 PM
+ */
+public enum QueryType {
+ PLAIN("plain"),
+ PREPARED("prepared"),
+ CALLABLE("callable"),
+ UNKNOWN("unknown");
+
+ private String description;
+
+ QueryType(String description) {
+ this.description = description;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+}
diff --git a/src/nl/astraeus/jdbc/example/JdbcStatisticsExample.java b/src/nl/astraeus/jdbc/example/JdbcStatisticsExample.java
new file mode 100644
index 0000000..07aac40
--- /dev/null
+++ b/src/nl/astraeus/jdbc/example/JdbcStatisticsExample.java
@@ -0,0 +1,68 @@
+package nl.astraeus.jdbc.example;
+
+import java.sql.*;
+
+/**
+ * User: rnentjes
+ * Date: 4/12/12
+ * Time: 7:32 PM
+ */
+public class JdbcStatisticsExample {
+
+
+ public static void main(String [] args) throws Exception {
+ Class.forName("org.h2.Driver");
+ Class.forName("nl.astraeus.jdbc.Driver");
+
+ new JdbcStatisticsExample();
+ }
+
+ public JdbcStatisticsExample() throws Exception {
+ Connection conn = DriverManager.getConnection("jdbc:stat:jdbc:h2:mem:test");
+
+ Statement statement = null;
+
+ statement = conn.createStatement();
+ statement.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))");
+ statement.close();
+
+ boolean running = true;
+ int count = 1;
+ PreparedStatement ps = null;
+
+ while (running) {
+ Thread.sleep(10);
+
+ String TableName = "TEST"+(System.nanoTime() % 1000);
+
+ try {
+ ps = conn.prepareStatement("SELECT COUNT(*) FROM "+TableName);
+ ResultSet rs = ps.executeQuery();
+ } catch (SQLException e) {
+ statement = conn.createStatement();
+ statement.execute("CREATE TABLE "+TableName+" (ID INT PRIMARY KEY, NAME VARCHAR(255))");
+ statement.close();
+ } finally {
+ if (ps!=null) {
+ ps.close();
+ }
+ }
+
+ ps = conn.prepareStatement("INSERT INTO "+TableName+" VALUES (?, ?)");
+
+ ps.setInt(1, count++);
+ ps.setString(2, "String "+System.currentTimeMillis());
+
+ ps.execute();
+ ps.close();
+
+ Thread.sleep(10);
+
+ ps = conn.prepareStatement("SELECT * FROM "+TableName);
+ ResultSet rs = ps.executeQuery();
+ statement.close();
+ }
+
+ conn.close();
+ }
+}
diff --git a/src/nl/astraeus/jdbc/util/IOUtils.java b/src/nl/astraeus/jdbc/util/IOUtils.java
new file mode 100644
index 0000000..ce95d9d
--- /dev/null
+++ b/src/nl/astraeus/jdbc/util/IOUtils.java
@@ -0,0 +1,38 @@
+package nl.astraeus.jdbc.util;
+
+import java.io.*;
+
+/**
+ * User: rnentjes
+ * Date: 4/9/12
+ * Time: 2:33 PM
+ */
+public class IOUtils {
+
+ public static String toString(InputStream in) throws IOException {
+ assert in != null;
+
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ StringBuilder buffer = new StringBuilder();
+
+ while(reader.ready()) {
+ buffer.append(reader.readLine());
+ buffer.append("\n");
+ }
+
+ return buffer.toString();
+ } finally {
+ in.close();
+ }
+ }
+
+ public static void copy(InputStream in, OutputStream out) throws IOException {
+ byte [] buffer = new byte[1<<16];
+ int bytes;
+
+ while((bytes = in.read(buffer)) > 0) {
+ out.write(buffer, 0, bytes);
+ }
+ }
+}
diff --git a/src/nl/astraeus/jdbc/util/Util.java b/src/nl/astraeus/jdbc/util/Util.java
new file mode 100644
index 0000000..eaa853b
--- /dev/null
+++ b/src/nl/astraeus/jdbc/util/Util.java
@@ -0,0 +1,25 @@
+package nl.astraeus.jdbc.util;
+
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+
+/**
+ * User: rnentjes
+ * Date: 3/28/12
+ * Time: 12:28 PM
+ */
+public class Util {
+ // utility functions
+ public static String formatNano(long l) {
+ NumberFormat format = new DecimalFormat("###,##0.000000");
+
+ return format.format((double) l / 1000000.0);
+ }
+
+ public static void printMemoryUsage() {
+ System.out.println("Used memory: "+((Runtime.getRuntime().totalMemory() / (1024*1024))-(Runtime.getRuntime().freeMemory() / (1024*1024))));
+ System.out.println("Free memory: "+(Runtime.getRuntime().freeMemory() / (1024*1024)));
+ System.out.println("Total memory: "+(Runtime.getRuntime().totalMemory() / (1024*1024)));
+ System.out.println("Max memory: "+(Runtime.getRuntime().maxMemory() / (1024*1024)));
+ }
+}
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..275077f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README b/README
deleted file mode 100644
index 734abaf..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-This file was created by IntelliJ IDEA 11.1.1 for binding GitHub repository
\ No newline at end of file
diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml
new file mode 100644
index 0000000..ca90a9b
--- /dev/null
+++ b/Simple-jdbc-statistics.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/h2-1.3.166.jar b/lib/h2-1.3.166.jar
new file mode 100644
index 0000000..4985063
--- /dev/null
+++ b/lib/h2-1.3.166.jar
Binary files differ
diff --git a/lib/servlet-api-2.5.jar b/lib/servlet-api-2.5.jar
new file mode 100644
index 0000000..20b5755
--- /dev/null
+++ b/lib/servlet-api-2.5.jar
Binary files differ
diff --git a/lib/slf4j-api-1.6.4.jar b/lib/slf4j-api-1.6.4.jar
new file mode 100644
index 0000000..4d23f41
--- /dev/null
+++ b/lib/slf4j-api-1.6.4.jar
Binary files differ
diff --git a/lib/slf4j-simple-1.6.4.jar b/lib/slf4j-simple-1.6.4.jar
new file mode 100644
index 0000000..3d1b8d9
--- /dev/null
+++ b/lib/slf4j-simple-1.6.4.jar
Binary files differ
diff --git a/lib/ssr-0.1.jar b/lib/ssr-0.1.jar
new file mode 100644
index 0000000..65dfcf4
--- /dev/null
+++ b/lib/ssr-0.1.jar
Binary files differ
diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar
new file mode 100644
index 0000000..db63792
--- /dev/null
+++ b/lib/vst-0.4.jar
Binary files differ
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..ac2dbe1
--- /dev/null
+++ b/readme.md
@@ -0,0 +1 @@
+A simple wrapper around jdbc drivers what will show current jdbc stats of the running queries on a simple web page on port 18080.
\ No newline at end of file
diff --git a/src/nl/astraeus/jdbc/ConnectionLogger.java b/src/nl/astraeus/jdbc/ConnectionLogger.java
new file mode 100644
index 0000000..c3e243f
--- /dev/null
+++ b/src/nl/astraeus/jdbc/ConnectionLogger.java
@@ -0,0 +1,279 @@
+package nl.astraeus.jdbc;
+
+import java.sql.*;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:12:34 PM
+ */
+public class ConnectionLogger implements Connection {
+ private Connection connection;
+
+ private long milli;
+ private long nano;
+ private String lastSql;
+
+ public ConnectionLogger(Connection connection) {
+ this.connection = connection;
+ this.lastSql = "";
+ }
+
+ private void clearTime() {
+ milli = System.currentTimeMillis();
+ nano = System.nanoTime();
+ }
+
+ private void log(String sql) {
+ long m = System.currentTimeMillis() - milli;
+ long n = System.nanoTime() - nano;
+
+ JdbcLogger.log(QueryType.UNKNOWN, sql, m, n);
+ }
+
+ public void commit() throws SQLException {
+ clearTime();
+
+ connection.commit();
+
+ log("commit");
+ }
+
+ public void rollback() throws SQLException {
+ clearTime();
+
+ connection.rollback();
+
+ log("rollback");
+ }
+
+ public void close() throws SQLException {
+ clearTime();
+
+ connection.close();
+
+ log("close");
+ }
+
+ public PreparedStatement prepareStatement(String sql) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, autoGeneratedKeys);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int columnIndexes[]) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, columnIndexes);
+ }
+
+ public PreparedStatement prepareStatement(String sql, String columnNames[]) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, columnNames);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ public Statement createStatement() throws SQLException {
+ return connection.createStatement();
+ }
+
+ public CallableStatement prepareCall(String sql) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql);
+ }
+
+ public String nativeSQL(String sql) throws SQLException {
+ lastSql = sql;
+ return connection.nativeSQL(sql);
+ }
+
+ public void setAutoCommit(boolean autoCommit) throws SQLException {
+ connection.setAutoCommit(autoCommit);
+ }
+
+ public boolean getAutoCommit() throws SQLException {
+ return connection.getAutoCommit();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return connection.isClosed();
+ }
+
+ public DatabaseMetaData getMetaData() throws SQLException {
+ return connection.getMetaData();
+ }
+
+ public void setReadOnly(boolean readOnly) throws SQLException {
+ connection.setReadOnly(readOnly);
+ }
+
+ public boolean isReadOnly() throws SQLException {
+ return connection.isReadOnly();
+ }
+
+ public void setCatalog(String catalog) throws SQLException {
+ connection.setCatalog(catalog);
+ }
+
+ public String getCatalog() throws SQLException {
+ return connection.getCatalog();
+ }
+
+ public void setTransactionIsolation(int level) throws SQLException {
+ connection.setTransactionIsolation(level);
+ }
+
+ public int getTransactionIsolation() throws SQLException {
+ return connection.getTransactionIsolation();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return connection.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ connection.clearWarnings();
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency);
+ }
+
+ public Map> getTypeMap() throws SQLException {
+ return connection.getTypeMap();
+ }
+
+ public void setTypeMap(Map> map) throws SQLException {
+ connection.setTypeMap(map);
+ }
+
+ public void setHoldability(int holdability) throws SQLException {
+ connection.setHoldability(holdability);
+ }
+
+ public int getHoldability() throws SQLException {
+ return connection.getHoldability();
+ }
+
+ public Savepoint setSavepoint() throws SQLException {
+ return connection.setSavepoint();
+ }
+
+ public Savepoint setSavepoint(String name) throws SQLException {
+ return connection.setSavepoint(name);
+ }
+
+ public void rollback(Savepoint savepoint) throws SQLException {
+ connection.rollback();
+ }
+
+ public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+ connection.releaseSavepoint(savepoint);
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ public Clob createClob() throws SQLException {
+ return connection.createClob();
+ }
+
+ public Blob createBlob() throws SQLException {
+ return connection.createBlob();
+ }
+
+ public NClob createNClob() throws SQLException {
+ return connection.createNClob();
+ }
+
+ public SQLXML createSQLXML() throws SQLException {
+ return connection.createSQLXML();
+ }
+
+ public boolean isValid(int timeout) throws SQLException {
+ return connection.isValid(timeout);
+ }
+
+ public void setClientInfo(String name, String value) throws SQLClientInfoException {
+ connection.setClientInfo(name, value);
+ }
+
+ public void setClientInfo(Properties properties) throws SQLClientInfoException {
+ connection.setClientInfo(properties);
+ }
+
+ public String getClientInfo(String name) throws SQLException {
+ return connection.getClientInfo(name);
+ }
+
+ public Properties getClientInfo() throws SQLException {
+ return connection.getClientInfo();
+ }
+
+ public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
+ return connection.createArrayOf(typeName, elements);
+ }
+
+ public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
+ return connection.createStruct(typeName, attributes);
+ }
+
+ @Override
+ public void setSchema(String schema) throws SQLException {
+ connection.setSchema(schema);
+ }
+
+ @Override
+ public String getSchema() throws SQLException {
+ return connection.getSchema();
+ }
+
+ @Override
+ public void abort(Executor executor) throws SQLException {
+ connection.abort(executor);
+ }
+
+ @Override
+ public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
+ connection.setNetworkTimeout(executor, milliseconds);
+ }
+
+ @Override
+ public int getNetworkTimeout() throws SQLException {
+ return connection.getNetworkTimeout();
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return connection.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return connection.isWrapperFor(iface);
+ }
+}
diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java
new file mode 100644
index 0000000..8317172
--- /dev/null
+++ b/src/nl/astraeus/jdbc/Driver.java
@@ -0,0 +1,116 @@
+package nl.astraeus.jdbc;
+
+import nl.astraeus.http.SimpleWebServer;
+import nl.astraeus.jdbc.web.JdbcStatisticsServlet;
+import nl.astraeus.jdbc.web.ResourceServlet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.*;
+import java.util.Enumeration;
+import java.util.Properties;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:54:37 PM
+ */
+public class Driver implements java.sql.Driver {
+ private final static Logger log = LoggerFactory.getLogger(Driver.class);
+
+ final private static String URL_PREFIX = "jdbc:stat:";
+
+ private java.sql.Driver driver = null;
+ private String[] drivers = {
+ "org.postgresql.Driver",
+ "oracle.jdbc.driver.OracleDriver",
+ "com.sybase.jdbc2.jdbc.SybDriver",
+ "net.sourceforge.jtds.jdbc.Driver",
+ "com.microsoft.jdbc.sqlserver.SQLServerDriver",
+ "com.microsoft.sqlserver.jdbc.SQLServerDriver",
+ "weblogic.jdbc.sqlserver.SQLServerDriver",
+ "com.informix.jdbc.IfxDriver",
+ "org.apache.derby.jdbc.ClientDriver",
+ "org.apache.derby.jdbc.EmbeddedDriver",
+ "com.mysql.jdbc.Driver",
+ "org.hsqldb.jdbcDriver",
+ "org.h2.Driver" };
+
+ static {
+ log.debug("Loading driver class " + Driver.class.getName());
+
+ try {
+ DriverManager.registerDriver(new Driver());
+ } catch (SQLException e) {
+ log.error("", e);
+ }
+ }
+
+ public Driver() {
+ for (String dr : drivers) {
+ try {
+ Class.forName(dr);
+ } catch (Throwable e) {
+ log.debug("Can't instantiate driver: " + dr, e);
+ }
+ }
+ }
+
+ private java.sql.Driver findDriver(String url) throws SQLException {
+ Enumeration e = DriverManager.getDrivers();
+
+ while (e.hasMoreElements()) {
+ java.sql.Driver d = (java.sql.Driver) e.nextElement();
+
+ if (d.acceptsURL(url)) {
+ return d;
+ }
+ }
+
+ throw new SQLException("Driver not found: " + url);
+ }
+
+ public Connection connect(String url, Properties info) throws SQLException {
+ url = url.substring(URL_PREFIX.length());
+
+ if (driver == null) {
+ driver = findDriver(url);
+ }
+
+ if (driver != null) {
+ SimpleWebServer server = new SimpleWebServer(18080);
+
+ server.addServlet(new JdbcStatisticsServlet(), "/");
+ server.addServlet(new ResourceServlet(), "/resources/*");
+
+ server.start();
+ }
+
+ return new ConnectionLogger(driver.connect(url, info));
+ }
+
+ public boolean acceptsURL(String url) throws SQLException {
+ return (url != null && url.startsWith(URL_PREFIX));
+ }
+
+ public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
+ return driver.getPropertyInfo(url, info);
+ }
+
+ public int getMajorVersion() {
+ return driver.getMajorVersion();
+ }
+
+ public int getMinorVersion() {
+ return driver.getMinorVersion();
+ }
+
+ public boolean jdbcCompliant() {
+ return driver.jdbcCompliant();
+ }
+
+ @Override
+ public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ return driver.getParentLogger();
+ }
+}
diff --git a/src/nl/astraeus/jdbc/JdbcLogger.java b/src/nl/astraeus/jdbc/JdbcLogger.java
new file mode 100644
index 0000000..f4bc125
--- /dev/null
+++ b/src/nl/astraeus/jdbc/JdbcLogger.java
@@ -0,0 +1,113 @@
+package nl.astraeus.jdbc;
+
+import nl.astraeus.jdbc.util.Util;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * User: riennentjes
+ * Date: Jul 12, 2008
+ * Time: 9:15:21 AM
+ */
+public class JdbcLogger {
+ private final static Logger logger = LoggerFactory.getLogger(JdbcLogger.class);
+
+ private final static JdbcLogger instance = new JdbcLogger();
+
+ public static JdbcLogger get() {
+ return instance;
+ }
+
+ public final static class LogEntry {
+ public QueryType type;
+ public String sql;
+ public long milli;
+ public long nano;
+ public int count;
+ public int hash;
+
+ public LogEntry(int hash, QueryType type, String sql, long milli, long nano) {
+ this.hash = hash;
+ this.type = type;
+ this.sql = sql;
+ this.milli = milli;
+ this.nano = nano;
+ this.count = 1;
+ }
+
+ public void addCount(long milli, long nano) {
+ synchronized (this) {
+ count++;
+ this.milli += milli;
+ this.nano += nano;
+ }
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public String getMilli() {
+ return Util.formatNano(milli*1000000/count);
+ }
+
+ public String getNano() {
+ return Util.formatNano(nano/count);
+ }
+
+ public String getTotal() {
+ return Util.formatNano(nano);
+ }
+
+ public String getSql() {
+ return sql;
+ }
+ }
+
+ private Map queries;
+
+ public JdbcLogger() {
+ queries = new ConcurrentHashMap();
+ }
+
+ public void logEntry(QueryType type, String sql, long milli, long nano) {
+ int hash = sql.hashCode();
+ LogEntry entry = queries.get(hash);
+
+ if (entry == null) {
+ entry = new LogEntry(hash, type, sql, milli, nano);
+ queries.put(hash, entry);
+ } else {
+ entry.addCount(milli, nano);
+ }
+
+ if (queries.size() > 1000) {
+ List toRemove = new LinkedList();
+ List values = new LinkedList(queries.values());
+
+ Collections.sort(values, new Comparator() {
+ @Override
+ public int compare(LogEntry o1, LogEntry o2) {
+ return o1.count - o2.count;
+ }
+ });
+
+ while (queries.size() > 900) {
+ queries.remove(values.remove(0).hash);
+
+ }
+ }
+ }
+
+ public static void log(QueryType type, String sql, long milli, long nano) {
+ instance.logEntry(type, sql, milli, nano);
+ }
+
+ public Collection getEntries() {
+ return queries.values();
+ }
+
+}
diff --git a/src/nl/astraeus/jdbc/PreparedStatementLogger.java b/src/nl/astraeus/jdbc/PreparedStatementLogger.java
new file mode 100644
index 0000000..98aefc7
--- /dev/null
+++ b/src/nl/astraeus/jdbc/PreparedStatementLogger.java
@@ -0,0 +1,577 @@
+package nl.astraeus.jdbc;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.*;
+import java.util.Calendar;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 7:47:57 PM
+ */
+public class PreparedStatementLogger implements PreparedStatement {
+ private final static Logger log = LoggerFactory.getLogger(PreparedStatementLogger.class);
+
+ private PreparedStatement statement;
+
+ private String sql;
+ private QueryType type;
+ private long milli;
+ private long nano;
+
+ //private ArrayList parameters;
+
+ public PreparedStatementLogger(PreparedStatement statement) {
+ this.statement = statement;
+ this.sql = "";
+ this.type = QueryType.UNKNOWN;
+ }
+
+ private void clearTime() {
+ milli = System.currentTimeMillis();
+ nano = System.nanoTime();
+ }
+
+ private void log(QueryType type, String sql) {
+ long m = System.currentTimeMillis() - milli;
+ long n = System.nanoTime() - nano;
+
+ JdbcLogger.log(type, sql, m, n);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, resultSetType, resultSetConcurrency);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, autoGeneratedKeys);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int[] columnIndexes) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, columnIndexes);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, String[] columnNames) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, columnNames);
+ }
+
+ public boolean execute() throws SQLException {
+ clearTime();
+
+ boolean result = statement.execute();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public ResultSet executeQuery() throws SQLException {
+ clearTime();
+
+ ResultSet result = statement.executeQuery();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate() throws SQLException {
+ clearTime();
+
+ int result = statement.executeUpdate();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public ResultSet executeQuery(String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ ResultSet result = statement.executeQuery(sql);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, autoGeneratedKeys);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, int columnIndexes[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, columnIndexes);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, String columnNames[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, columnNames);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, autoGeneratedKeys);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, int columnIndexes[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, columnIndexes);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, String columnNames[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, columnNames);
+
+ log(type, sql);
+
+ return result;
+ }
+
+
+ public void setNull(int parameterIndex, int sqlType) throws SQLException {
+ statement.setNull(parameterIndex, sqlType);
+ }
+
+ public void setBoolean(int parameterIndex, boolean x) throws SQLException {
+ statement.setBoolean(parameterIndex, x);
+ }
+
+ public void setByte(int parameterIndex, byte x) throws SQLException {
+ statement.setByte(parameterIndex, x);
+ }
+
+ public void setShort(int parameterIndex, short x) throws SQLException {
+ statement.setShort(parameterIndex, x);
+ }
+
+ public void setInt(int parameterIndex, int x) throws SQLException {
+ statement.setInt(parameterIndex, x);
+ }
+
+ public void setLong(int parameterIndex, long x) throws SQLException {
+ statement.setLong(parameterIndex, x);
+ }
+
+ public void setFloat(int parameterIndex, float x) throws SQLException {
+ statement.setFloat(parameterIndex, x);
+ }
+
+ public void setDouble(int parameterIndex, double x) throws SQLException {
+ statement.setDouble(parameterIndex, x);
+ }
+
+ public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
+ statement.setBigDecimal(parameterIndex, x);
+ }
+
+ public void setString(int parameterIndex, String x) throws SQLException {
+ statement.setString(parameterIndex, x);
+ }
+
+ public void setBytes(int parameterIndex, byte x[]) throws SQLException {
+ statement.setBytes(parameterIndex, x);
+ }
+
+ public void setDate(int parameterIndex, Date x) throws SQLException {
+ statement.setDate(parameterIndex, x);
+ }
+
+ public void setTime(int parameterIndex, Time x) throws SQLException {
+ statement.setTime(parameterIndex, x);
+ }
+
+ public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
+ statement.setTimestamp(parameterIndex, x);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x, length);
+ }
+
+ public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setUnicodeStream(parameterIndex, x, length);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x, length);
+ }
+
+ public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
+ statement.setObject(parameterIndex, x, targetSqlType);
+ }
+
+ public void setObject(int parameterIndex, Object x) throws SQLException {
+ statement.setObject(parameterIndex, x);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ public void setRef(int parameterIndex, Ref x) throws SQLException {
+ statement.setRef(parameterIndex, x);
+ }
+
+ public void setBlob(int parameterIndex, Blob x) throws SQLException {
+ statement.setBlob(parameterIndex, x);
+ }
+
+ public void setClob(int parameterIndex, Clob x) throws SQLException {
+ statement.setClob(parameterIndex, x);
+ }
+
+ public void setArray(int parameterIndex, Array x) throws SQLException {
+ statement.setArray(parameterIndex, x);
+ }
+
+ public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
+ statement.setDate(parameterIndex, x, cal);
+ }
+
+ public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
+ statement.setTime(parameterIndex, x, cal);
+ }
+
+ public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
+ statement.setTimestamp(parameterIndex, x, cal);
+ }
+
+ public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
+ statement.setNull(parameterIndex, sqlType, typeName);
+ }
+
+ public void setURL(int parameterIndex, URL x) throws SQLException {
+ statement.setURL(parameterIndex, x);
+ }
+
+ public void setRowId(int parameterIndex, RowId x) throws SQLException {
+ statement.setRowId(parameterIndex, x);
+ }
+
+ public void setNString(int parameterIndex, String value) throws SQLException {
+ statement.setNString(parameterIndex, value);
+ }
+
+ public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
+ statement.setNCharacterStream(parameterIndex, value, length);
+ }
+
+ public void setNClob(int parameterIndex, NClob value) throws SQLException {
+ statement.setNClob(parameterIndex, value);
+ }
+
+ public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setClob(parameterIndex, reader, length);
+ }
+
+ public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
+ statement.setBlob(parameterIndex, inputStream, length);
+ }
+
+ public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setNClob(parameterIndex, reader, length);
+ }
+
+ public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
+ statement.setSQLXML(parameterIndex, xmlObject);
+ }
+
+ public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException {
+ statement.setObject(parameterIndex, x, targetSqlType, scaleOrLength);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x, length);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x, length);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader);
+ }
+
+ public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
+ statement.setNCharacterStream(parameterIndex, value);
+ }
+
+ public void setClob(int parameterIndex, Reader reader) throws SQLException {
+ statement.setClob(parameterIndex, reader);
+ }
+
+ public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
+ statement.setBlob(parameterIndex, inputStream);
+ }
+
+ public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+ statement.setNClob(parameterIndex, reader);
+ }
+
+
+ public void close() throws SQLException {
+ sql = "";
+ type = QueryType.UNKNOWN;
+ milli = 0;
+ nano = 0;
+
+ statement.close();
+ }
+
+ public ResultSetMetaData getMetaData() throws SQLException {
+ return statement.getMetaData();
+ }
+
+ public void clearParameters() throws SQLException {
+ statement.clearParameters();
+ }
+
+ public ParameterMetaData getParameterMetaData() throws SQLException {
+ return statement.getParameterMetaData();
+ }
+
+ public void addBatch() throws SQLException {
+ statement.addBatch();
+ }
+
+ public int getMaxFieldSize() throws SQLException {
+ return statement.getMaxFieldSize();
+ }
+
+ public void setMaxFieldSize(int max) throws SQLException {
+ statement.setMaxFieldSize(max);
+ }
+
+ public int getMaxRows() throws SQLException {
+ return statement.getMaxRows();
+ }
+
+ public void setMaxRows(int max) throws SQLException {
+ statement.setMaxRows(max);
+ }
+
+ public void setEscapeProcessing(boolean enable) throws SQLException {
+ statement.setEscapeProcessing(enable);
+ }
+
+ public int getQueryTimeout() throws SQLException {
+ return statement.getQueryTimeout();
+ }
+
+ public void setQueryTimeout(int seconds) throws SQLException {
+ statement.setQueryTimeout(seconds);
+ }
+
+ public void cancel() throws SQLException {
+ statement.cancel();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return statement.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ statement.clearWarnings();
+ }
+
+ public void setCursorName(String name) throws SQLException {
+ statement.setCursorName(name);
+ }
+
+ public boolean execute(String sql) throws SQLException {
+ return statement.execute(sql);
+ }
+
+ public ResultSet getResultSet() throws SQLException {
+ return statement.getResultSet();
+ }
+
+ public int getUpdateCount() throws SQLException {
+ return statement.getUpdateCount();
+ }
+
+ public boolean getMoreResults() throws SQLException {
+ return statement.getMoreResults();
+ }
+
+ public void setFetchDirection(int direction) throws SQLException {
+ statement.setFetchDirection(direction);
+ }
+
+ public int getFetchDirection() throws SQLException {
+ return statement.getFetchDirection();
+ }
+
+ public void setFetchSize(int rows) throws SQLException {
+ statement.setFetchSize(rows);
+ }
+
+ public int getFetchSize() throws SQLException {
+ return statement.getFetchSize();
+ }
+
+ public int getResultSetConcurrency() throws SQLException {
+ return statement.getResultSetConcurrency();
+ }
+
+ public int getResultSetType() throws SQLException {
+ return statement.getResultSetType();
+ }
+
+ public void addBatch(String sql) throws SQLException {
+ statement.addBatch(sql);
+ }
+
+ public void clearBatch() throws SQLException {
+ statement.clearBatch();
+ }
+
+ public int[] executeBatch() throws SQLException {
+ return statement.executeBatch();
+ }
+
+ public Connection getConnection() throws SQLException {
+ return statement.getConnection();
+ }
+
+ public boolean getMoreResults(int current) throws SQLException {
+ return statement.getMoreResults(current);
+ }
+
+ public ResultSet getGeneratedKeys() throws SQLException {
+ return statement.getGeneratedKeys();
+ }
+
+ public int getResultSetHoldability() throws SQLException {
+ return statement.getResultSetHoldability();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return statement.isClosed();
+ }
+
+ public void setPoolable(boolean poolable) throws SQLException {
+ statement.setPoolable(poolable);
+ }
+
+ public boolean isPoolable() throws SQLException {
+ return statement.isPoolable();
+ }
+
+ @Override
+ public void closeOnCompletion() throws SQLException {
+ statement.closeOnCompletion();;
+ }
+
+ @Override
+ public boolean isCloseOnCompletion() throws SQLException {
+ return statement.isCloseOnCompletion();
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return statement.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return statement.isWrapperFor(iface);
+ }
+}
diff --git a/src/nl/astraeus/jdbc/QueryType.java b/src/nl/astraeus/jdbc/QueryType.java
new file mode 100644
index 0000000..744fbfc
--- /dev/null
+++ b/src/nl/astraeus/jdbc/QueryType.java
@@ -0,0 +1,24 @@
+package nl.astraeus.jdbc;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:32:49 PM
+ */
+public enum QueryType {
+ PLAIN("plain"),
+ PREPARED("prepared"),
+ CALLABLE("callable"),
+ UNKNOWN("unknown");
+
+ private String description;
+
+ QueryType(String description) {
+ this.description = description;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+}
diff --git a/src/nl/astraeus/jdbc/example/JdbcStatisticsExample.java b/src/nl/astraeus/jdbc/example/JdbcStatisticsExample.java
new file mode 100644
index 0000000..07aac40
--- /dev/null
+++ b/src/nl/astraeus/jdbc/example/JdbcStatisticsExample.java
@@ -0,0 +1,68 @@
+package nl.astraeus.jdbc.example;
+
+import java.sql.*;
+
+/**
+ * User: rnentjes
+ * Date: 4/12/12
+ * Time: 7:32 PM
+ */
+public class JdbcStatisticsExample {
+
+
+ public static void main(String [] args) throws Exception {
+ Class.forName("org.h2.Driver");
+ Class.forName("nl.astraeus.jdbc.Driver");
+
+ new JdbcStatisticsExample();
+ }
+
+ public JdbcStatisticsExample() throws Exception {
+ Connection conn = DriverManager.getConnection("jdbc:stat:jdbc:h2:mem:test");
+
+ Statement statement = null;
+
+ statement = conn.createStatement();
+ statement.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))");
+ statement.close();
+
+ boolean running = true;
+ int count = 1;
+ PreparedStatement ps = null;
+
+ while (running) {
+ Thread.sleep(10);
+
+ String TableName = "TEST"+(System.nanoTime() % 1000);
+
+ try {
+ ps = conn.prepareStatement("SELECT COUNT(*) FROM "+TableName);
+ ResultSet rs = ps.executeQuery();
+ } catch (SQLException e) {
+ statement = conn.createStatement();
+ statement.execute("CREATE TABLE "+TableName+" (ID INT PRIMARY KEY, NAME VARCHAR(255))");
+ statement.close();
+ } finally {
+ if (ps!=null) {
+ ps.close();
+ }
+ }
+
+ ps = conn.prepareStatement("INSERT INTO "+TableName+" VALUES (?, ?)");
+
+ ps.setInt(1, count++);
+ ps.setString(2, "String "+System.currentTimeMillis());
+
+ ps.execute();
+ ps.close();
+
+ Thread.sleep(10);
+
+ ps = conn.prepareStatement("SELECT * FROM "+TableName);
+ ResultSet rs = ps.executeQuery();
+ statement.close();
+ }
+
+ conn.close();
+ }
+}
diff --git a/src/nl/astraeus/jdbc/util/IOUtils.java b/src/nl/astraeus/jdbc/util/IOUtils.java
new file mode 100644
index 0000000..ce95d9d
--- /dev/null
+++ b/src/nl/astraeus/jdbc/util/IOUtils.java
@@ -0,0 +1,38 @@
+package nl.astraeus.jdbc.util;
+
+import java.io.*;
+
+/**
+ * User: rnentjes
+ * Date: 4/9/12
+ * Time: 2:33 PM
+ */
+public class IOUtils {
+
+ public static String toString(InputStream in) throws IOException {
+ assert in != null;
+
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ StringBuilder buffer = new StringBuilder();
+
+ while(reader.ready()) {
+ buffer.append(reader.readLine());
+ buffer.append("\n");
+ }
+
+ return buffer.toString();
+ } finally {
+ in.close();
+ }
+ }
+
+ public static void copy(InputStream in, OutputStream out) throws IOException {
+ byte [] buffer = new byte[1<<16];
+ int bytes;
+
+ while((bytes = in.read(buffer)) > 0) {
+ out.write(buffer, 0, bytes);
+ }
+ }
+}
diff --git a/src/nl/astraeus/jdbc/util/Util.java b/src/nl/astraeus/jdbc/util/Util.java
new file mode 100644
index 0000000..eaa853b
--- /dev/null
+++ b/src/nl/astraeus/jdbc/util/Util.java
@@ -0,0 +1,25 @@
+package nl.astraeus.jdbc.util;
+
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+
+/**
+ * User: rnentjes
+ * Date: 3/28/12
+ * Time: 12:28 PM
+ */
+public class Util {
+ // utility functions
+ public static String formatNano(long l) {
+ NumberFormat format = new DecimalFormat("###,##0.000000");
+
+ return format.format((double) l / 1000000.0);
+ }
+
+ public static void printMemoryUsage() {
+ System.out.println("Used memory: "+((Runtime.getRuntime().totalMemory() / (1024*1024))-(Runtime.getRuntime().freeMemory() / (1024*1024))));
+ System.out.println("Free memory: "+(Runtime.getRuntime().freeMemory() / (1024*1024)));
+ System.out.println("Total memory: "+(Runtime.getRuntime().totalMemory() / (1024*1024)));
+ System.out.println("Max memory: "+(Runtime.getRuntime().maxMemory() / (1024*1024)));
+ }
+}
diff --git a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java
new file mode 100644
index 0000000..a162d6f
--- /dev/null
+++ b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java
@@ -0,0 +1,90 @@
+package nl.astraeus.jdbc.web;
+
+import nl.astraeus.jdbc.util.IOUtils;
+import nl.astraeus.jdbc.util.Util;
+import nl.astraeus.jdbc.web.page.Menu;
+import nl.astraeus.jdbc.web.page.Page;
+import nl.astraeus.jdbc.web.page.QueryOverview;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+
+/**
+ * User: rnentjes
+ * Date: 3/28/12
+ * Time: 3:05 PM
+ */
+public class JdbcStatisticsServlet extends HttpServlet {
+
+ private String head;
+ private String bottom;
+
+ @Override
+ public void init() throws ServletException {
+ super.init();
+
+ try {
+ head = IOUtils.toString(getClass().getResourceAsStream("head.html"));
+ bottom = IOUtils.toString(getClass().getResourceAsStream("bottom.html"));
+ } catch (IOException e) {
+ throw new ServletException(e);
+ }
+
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ doPost(req, resp);
+ }
+
+ @Override
+ protected void doPost(final HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ long nano = System.nanoTime();
+
+ HttpSession session = req.getSession();
+ boolean ajax = "true".equals(req.getParameter("ajax"));
+
+ resp.setContentType("text/html");
+
+ Page page = (Page)session.getAttribute("page");
+ Page menu = (Page)session.getAttribute("menu");
+
+ session.setMaxInactiveInterval(1800);
+
+ if (menu == null) {
+ menu = new Menu();
+
+ session.setAttribute("menu", menu);
+ }
+
+ if (page == null || "menumain".equals(req.getParameter("action"))) {
+ page = new QueryOverview();
+ } else if ("diagnostics".equals(req.getParameter("action"))) {
+ //page = new Diagnostics();
+ } else {
+ page = page .processRequest(req);
+ }
+
+ menu.processRequest(req);
+
+ session.setAttribute("page", page);
+
+ if (!ajax) {
+ resp.getWriter().print(head);
+ }
+
+ resp.getWriter().print(menu.render(req));
+ resp.getWriter().print(page.render(req));
+
+ if (!ajax) {
+ resp.getWriter().print(bottom);
+ }
+
+ System.out.println("Request ends, time="+ Util.formatNano(System.nanoTime() - nano) +", page="+page.getClass().getSimpleName());
+ }
+
+}
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..275077f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README b/README
deleted file mode 100644
index 734abaf..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-This file was created by IntelliJ IDEA 11.1.1 for binding GitHub repository
\ No newline at end of file
diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml
new file mode 100644
index 0000000..ca90a9b
--- /dev/null
+++ b/Simple-jdbc-statistics.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/h2-1.3.166.jar b/lib/h2-1.3.166.jar
new file mode 100644
index 0000000..4985063
--- /dev/null
+++ b/lib/h2-1.3.166.jar
Binary files differ
diff --git a/lib/servlet-api-2.5.jar b/lib/servlet-api-2.5.jar
new file mode 100644
index 0000000..20b5755
--- /dev/null
+++ b/lib/servlet-api-2.5.jar
Binary files differ
diff --git a/lib/slf4j-api-1.6.4.jar b/lib/slf4j-api-1.6.4.jar
new file mode 100644
index 0000000..4d23f41
--- /dev/null
+++ b/lib/slf4j-api-1.6.4.jar
Binary files differ
diff --git a/lib/slf4j-simple-1.6.4.jar b/lib/slf4j-simple-1.6.4.jar
new file mode 100644
index 0000000..3d1b8d9
--- /dev/null
+++ b/lib/slf4j-simple-1.6.4.jar
Binary files differ
diff --git a/lib/ssr-0.1.jar b/lib/ssr-0.1.jar
new file mode 100644
index 0000000..65dfcf4
--- /dev/null
+++ b/lib/ssr-0.1.jar
Binary files differ
diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar
new file mode 100644
index 0000000..db63792
--- /dev/null
+++ b/lib/vst-0.4.jar
Binary files differ
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..ac2dbe1
--- /dev/null
+++ b/readme.md
@@ -0,0 +1 @@
+A simple wrapper around jdbc drivers what will show current jdbc stats of the running queries on a simple web page on port 18080.
\ No newline at end of file
diff --git a/src/nl/astraeus/jdbc/ConnectionLogger.java b/src/nl/astraeus/jdbc/ConnectionLogger.java
new file mode 100644
index 0000000..c3e243f
--- /dev/null
+++ b/src/nl/astraeus/jdbc/ConnectionLogger.java
@@ -0,0 +1,279 @@
+package nl.astraeus.jdbc;
+
+import java.sql.*;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:12:34 PM
+ */
+public class ConnectionLogger implements Connection {
+ private Connection connection;
+
+ private long milli;
+ private long nano;
+ private String lastSql;
+
+ public ConnectionLogger(Connection connection) {
+ this.connection = connection;
+ this.lastSql = "";
+ }
+
+ private void clearTime() {
+ milli = System.currentTimeMillis();
+ nano = System.nanoTime();
+ }
+
+ private void log(String sql) {
+ long m = System.currentTimeMillis() - milli;
+ long n = System.nanoTime() - nano;
+
+ JdbcLogger.log(QueryType.UNKNOWN, sql, m, n);
+ }
+
+ public void commit() throws SQLException {
+ clearTime();
+
+ connection.commit();
+
+ log("commit");
+ }
+
+ public void rollback() throws SQLException {
+ clearTime();
+
+ connection.rollback();
+
+ log("rollback");
+ }
+
+ public void close() throws SQLException {
+ clearTime();
+
+ connection.close();
+
+ log("close");
+ }
+
+ public PreparedStatement prepareStatement(String sql) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, autoGeneratedKeys);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int columnIndexes[]) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, columnIndexes);
+ }
+
+ public PreparedStatement prepareStatement(String sql, String columnNames[]) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, columnNames);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ public Statement createStatement() throws SQLException {
+ return connection.createStatement();
+ }
+
+ public CallableStatement prepareCall(String sql) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql);
+ }
+
+ public String nativeSQL(String sql) throws SQLException {
+ lastSql = sql;
+ return connection.nativeSQL(sql);
+ }
+
+ public void setAutoCommit(boolean autoCommit) throws SQLException {
+ connection.setAutoCommit(autoCommit);
+ }
+
+ public boolean getAutoCommit() throws SQLException {
+ return connection.getAutoCommit();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return connection.isClosed();
+ }
+
+ public DatabaseMetaData getMetaData() throws SQLException {
+ return connection.getMetaData();
+ }
+
+ public void setReadOnly(boolean readOnly) throws SQLException {
+ connection.setReadOnly(readOnly);
+ }
+
+ public boolean isReadOnly() throws SQLException {
+ return connection.isReadOnly();
+ }
+
+ public void setCatalog(String catalog) throws SQLException {
+ connection.setCatalog(catalog);
+ }
+
+ public String getCatalog() throws SQLException {
+ return connection.getCatalog();
+ }
+
+ public void setTransactionIsolation(int level) throws SQLException {
+ connection.setTransactionIsolation(level);
+ }
+
+ public int getTransactionIsolation() throws SQLException {
+ return connection.getTransactionIsolation();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return connection.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ connection.clearWarnings();
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency);
+ }
+
+ public Map> getTypeMap() throws SQLException {
+ return connection.getTypeMap();
+ }
+
+ public void setTypeMap(Map> map) throws SQLException {
+ connection.setTypeMap(map);
+ }
+
+ public void setHoldability(int holdability) throws SQLException {
+ connection.setHoldability(holdability);
+ }
+
+ public int getHoldability() throws SQLException {
+ return connection.getHoldability();
+ }
+
+ public Savepoint setSavepoint() throws SQLException {
+ return connection.setSavepoint();
+ }
+
+ public Savepoint setSavepoint(String name) throws SQLException {
+ return connection.setSavepoint(name);
+ }
+
+ public void rollback(Savepoint savepoint) throws SQLException {
+ connection.rollback();
+ }
+
+ public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+ connection.releaseSavepoint(savepoint);
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ public Clob createClob() throws SQLException {
+ return connection.createClob();
+ }
+
+ public Blob createBlob() throws SQLException {
+ return connection.createBlob();
+ }
+
+ public NClob createNClob() throws SQLException {
+ return connection.createNClob();
+ }
+
+ public SQLXML createSQLXML() throws SQLException {
+ return connection.createSQLXML();
+ }
+
+ public boolean isValid(int timeout) throws SQLException {
+ return connection.isValid(timeout);
+ }
+
+ public void setClientInfo(String name, String value) throws SQLClientInfoException {
+ connection.setClientInfo(name, value);
+ }
+
+ public void setClientInfo(Properties properties) throws SQLClientInfoException {
+ connection.setClientInfo(properties);
+ }
+
+ public String getClientInfo(String name) throws SQLException {
+ return connection.getClientInfo(name);
+ }
+
+ public Properties getClientInfo() throws SQLException {
+ return connection.getClientInfo();
+ }
+
+ public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
+ return connection.createArrayOf(typeName, elements);
+ }
+
+ public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
+ return connection.createStruct(typeName, attributes);
+ }
+
+ @Override
+ public void setSchema(String schema) throws SQLException {
+ connection.setSchema(schema);
+ }
+
+ @Override
+ public String getSchema() throws SQLException {
+ return connection.getSchema();
+ }
+
+ @Override
+ public void abort(Executor executor) throws SQLException {
+ connection.abort(executor);
+ }
+
+ @Override
+ public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
+ connection.setNetworkTimeout(executor, milliseconds);
+ }
+
+ @Override
+ public int getNetworkTimeout() throws SQLException {
+ return connection.getNetworkTimeout();
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return connection.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return connection.isWrapperFor(iface);
+ }
+}
diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java
new file mode 100644
index 0000000..8317172
--- /dev/null
+++ b/src/nl/astraeus/jdbc/Driver.java
@@ -0,0 +1,116 @@
+package nl.astraeus.jdbc;
+
+import nl.astraeus.http.SimpleWebServer;
+import nl.astraeus.jdbc.web.JdbcStatisticsServlet;
+import nl.astraeus.jdbc.web.ResourceServlet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.*;
+import java.util.Enumeration;
+import java.util.Properties;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:54:37 PM
+ */
+public class Driver implements java.sql.Driver {
+ private final static Logger log = LoggerFactory.getLogger(Driver.class);
+
+ final private static String URL_PREFIX = "jdbc:stat:";
+
+ private java.sql.Driver driver = null;
+ private String[] drivers = {
+ "org.postgresql.Driver",
+ "oracle.jdbc.driver.OracleDriver",
+ "com.sybase.jdbc2.jdbc.SybDriver",
+ "net.sourceforge.jtds.jdbc.Driver",
+ "com.microsoft.jdbc.sqlserver.SQLServerDriver",
+ "com.microsoft.sqlserver.jdbc.SQLServerDriver",
+ "weblogic.jdbc.sqlserver.SQLServerDriver",
+ "com.informix.jdbc.IfxDriver",
+ "org.apache.derby.jdbc.ClientDriver",
+ "org.apache.derby.jdbc.EmbeddedDriver",
+ "com.mysql.jdbc.Driver",
+ "org.hsqldb.jdbcDriver",
+ "org.h2.Driver" };
+
+ static {
+ log.debug("Loading driver class " + Driver.class.getName());
+
+ try {
+ DriverManager.registerDriver(new Driver());
+ } catch (SQLException e) {
+ log.error("", e);
+ }
+ }
+
+ public Driver() {
+ for (String dr : drivers) {
+ try {
+ Class.forName(dr);
+ } catch (Throwable e) {
+ log.debug("Can't instantiate driver: " + dr, e);
+ }
+ }
+ }
+
+ private java.sql.Driver findDriver(String url) throws SQLException {
+ Enumeration e = DriverManager.getDrivers();
+
+ while (e.hasMoreElements()) {
+ java.sql.Driver d = (java.sql.Driver) e.nextElement();
+
+ if (d.acceptsURL(url)) {
+ return d;
+ }
+ }
+
+ throw new SQLException("Driver not found: " + url);
+ }
+
+ public Connection connect(String url, Properties info) throws SQLException {
+ url = url.substring(URL_PREFIX.length());
+
+ if (driver == null) {
+ driver = findDriver(url);
+ }
+
+ if (driver != null) {
+ SimpleWebServer server = new SimpleWebServer(18080);
+
+ server.addServlet(new JdbcStatisticsServlet(), "/");
+ server.addServlet(new ResourceServlet(), "/resources/*");
+
+ server.start();
+ }
+
+ return new ConnectionLogger(driver.connect(url, info));
+ }
+
+ public boolean acceptsURL(String url) throws SQLException {
+ return (url != null && url.startsWith(URL_PREFIX));
+ }
+
+ public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
+ return driver.getPropertyInfo(url, info);
+ }
+
+ public int getMajorVersion() {
+ return driver.getMajorVersion();
+ }
+
+ public int getMinorVersion() {
+ return driver.getMinorVersion();
+ }
+
+ public boolean jdbcCompliant() {
+ return driver.jdbcCompliant();
+ }
+
+ @Override
+ public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ return driver.getParentLogger();
+ }
+}
diff --git a/src/nl/astraeus/jdbc/JdbcLogger.java b/src/nl/astraeus/jdbc/JdbcLogger.java
new file mode 100644
index 0000000..f4bc125
--- /dev/null
+++ b/src/nl/astraeus/jdbc/JdbcLogger.java
@@ -0,0 +1,113 @@
+package nl.astraeus.jdbc;
+
+import nl.astraeus.jdbc.util.Util;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * User: riennentjes
+ * Date: Jul 12, 2008
+ * Time: 9:15:21 AM
+ */
+public class JdbcLogger {
+ private final static Logger logger = LoggerFactory.getLogger(JdbcLogger.class);
+
+ private final static JdbcLogger instance = new JdbcLogger();
+
+ public static JdbcLogger get() {
+ return instance;
+ }
+
+ public final static class LogEntry {
+ public QueryType type;
+ public String sql;
+ public long milli;
+ public long nano;
+ public int count;
+ public int hash;
+
+ public LogEntry(int hash, QueryType type, String sql, long milli, long nano) {
+ this.hash = hash;
+ this.type = type;
+ this.sql = sql;
+ this.milli = milli;
+ this.nano = nano;
+ this.count = 1;
+ }
+
+ public void addCount(long milli, long nano) {
+ synchronized (this) {
+ count++;
+ this.milli += milli;
+ this.nano += nano;
+ }
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public String getMilli() {
+ return Util.formatNano(milli*1000000/count);
+ }
+
+ public String getNano() {
+ return Util.formatNano(nano/count);
+ }
+
+ public String getTotal() {
+ return Util.formatNano(nano);
+ }
+
+ public String getSql() {
+ return sql;
+ }
+ }
+
+ private Map queries;
+
+ public JdbcLogger() {
+ queries = new ConcurrentHashMap();
+ }
+
+ public void logEntry(QueryType type, String sql, long milli, long nano) {
+ int hash = sql.hashCode();
+ LogEntry entry = queries.get(hash);
+
+ if (entry == null) {
+ entry = new LogEntry(hash, type, sql, milli, nano);
+ queries.put(hash, entry);
+ } else {
+ entry.addCount(milli, nano);
+ }
+
+ if (queries.size() > 1000) {
+ List toRemove = new LinkedList();
+ List values = new LinkedList(queries.values());
+
+ Collections.sort(values, new Comparator() {
+ @Override
+ public int compare(LogEntry o1, LogEntry o2) {
+ return o1.count - o2.count;
+ }
+ });
+
+ while (queries.size() > 900) {
+ queries.remove(values.remove(0).hash);
+
+ }
+ }
+ }
+
+ public static void log(QueryType type, String sql, long milli, long nano) {
+ instance.logEntry(type, sql, milli, nano);
+ }
+
+ public Collection getEntries() {
+ return queries.values();
+ }
+
+}
diff --git a/src/nl/astraeus/jdbc/PreparedStatementLogger.java b/src/nl/astraeus/jdbc/PreparedStatementLogger.java
new file mode 100644
index 0000000..98aefc7
--- /dev/null
+++ b/src/nl/astraeus/jdbc/PreparedStatementLogger.java
@@ -0,0 +1,577 @@
+package nl.astraeus.jdbc;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.*;
+import java.util.Calendar;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 7:47:57 PM
+ */
+public class PreparedStatementLogger implements PreparedStatement {
+ private final static Logger log = LoggerFactory.getLogger(PreparedStatementLogger.class);
+
+ private PreparedStatement statement;
+
+ private String sql;
+ private QueryType type;
+ private long milli;
+ private long nano;
+
+ //private ArrayList parameters;
+
+ public PreparedStatementLogger(PreparedStatement statement) {
+ this.statement = statement;
+ this.sql = "";
+ this.type = QueryType.UNKNOWN;
+ }
+
+ private void clearTime() {
+ milli = System.currentTimeMillis();
+ nano = System.nanoTime();
+ }
+
+ private void log(QueryType type, String sql) {
+ long m = System.currentTimeMillis() - milli;
+ long n = System.nanoTime() - nano;
+
+ JdbcLogger.log(type, sql, m, n);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, resultSetType, resultSetConcurrency);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, autoGeneratedKeys);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int[] columnIndexes) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, columnIndexes);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, String[] columnNames) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, columnNames);
+ }
+
+ public boolean execute() throws SQLException {
+ clearTime();
+
+ boolean result = statement.execute();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public ResultSet executeQuery() throws SQLException {
+ clearTime();
+
+ ResultSet result = statement.executeQuery();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate() throws SQLException {
+ clearTime();
+
+ int result = statement.executeUpdate();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public ResultSet executeQuery(String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ ResultSet result = statement.executeQuery(sql);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, autoGeneratedKeys);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, int columnIndexes[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, columnIndexes);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, String columnNames[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, columnNames);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, autoGeneratedKeys);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, int columnIndexes[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, columnIndexes);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, String columnNames[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, columnNames);
+
+ log(type, sql);
+
+ return result;
+ }
+
+
+ public void setNull(int parameterIndex, int sqlType) throws SQLException {
+ statement.setNull(parameterIndex, sqlType);
+ }
+
+ public void setBoolean(int parameterIndex, boolean x) throws SQLException {
+ statement.setBoolean(parameterIndex, x);
+ }
+
+ public void setByte(int parameterIndex, byte x) throws SQLException {
+ statement.setByte(parameterIndex, x);
+ }
+
+ public void setShort(int parameterIndex, short x) throws SQLException {
+ statement.setShort(parameterIndex, x);
+ }
+
+ public void setInt(int parameterIndex, int x) throws SQLException {
+ statement.setInt(parameterIndex, x);
+ }
+
+ public void setLong(int parameterIndex, long x) throws SQLException {
+ statement.setLong(parameterIndex, x);
+ }
+
+ public void setFloat(int parameterIndex, float x) throws SQLException {
+ statement.setFloat(parameterIndex, x);
+ }
+
+ public void setDouble(int parameterIndex, double x) throws SQLException {
+ statement.setDouble(parameterIndex, x);
+ }
+
+ public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
+ statement.setBigDecimal(parameterIndex, x);
+ }
+
+ public void setString(int parameterIndex, String x) throws SQLException {
+ statement.setString(parameterIndex, x);
+ }
+
+ public void setBytes(int parameterIndex, byte x[]) throws SQLException {
+ statement.setBytes(parameterIndex, x);
+ }
+
+ public void setDate(int parameterIndex, Date x) throws SQLException {
+ statement.setDate(parameterIndex, x);
+ }
+
+ public void setTime(int parameterIndex, Time x) throws SQLException {
+ statement.setTime(parameterIndex, x);
+ }
+
+ public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
+ statement.setTimestamp(parameterIndex, x);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x, length);
+ }
+
+ public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setUnicodeStream(parameterIndex, x, length);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x, length);
+ }
+
+ public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
+ statement.setObject(parameterIndex, x, targetSqlType);
+ }
+
+ public void setObject(int parameterIndex, Object x) throws SQLException {
+ statement.setObject(parameterIndex, x);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ public void setRef(int parameterIndex, Ref x) throws SQLException {
+ statement.setRef(parameterIndex, x);
+ }
+
+ public void setBlob(int parameterIndex, Blob x) throws SQLException {
+ statement.setBlob(parameterIndex, x);
+ }
+
+ public void setClob(int parameterIndex, Clob x) throws SQLException {
+ statement.setClob(parameterIndex, x);
+ }
+
+ public void setArray(int parameterIndex, Array x) throws SQLException {
+ statement.setArray(parameterIndex, x);
+ }
+
+ public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
+ statement.setDate(parameterIndex, x, cal);
+ }
+
+ public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
+ statement.setTime(parameterIndex, x, cal);
+ }
+
+ public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
+ statement.setTimestamp(parameterIndex, x, cal);
+ }
+
+ public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
+ statement.setNull(parameterIndex, sqlType, typeName);
+ }
+
+ public void setURL(int parameterIndex, URL x) throws SQLException {
+ statement.setURL(parameterIndex, x);
+ }
+
+ public void setRowId(int parameterIndex, RowId x) throws SQLException {
+ statement.setRowId(parameterIndex, x);
+ }
+
+ public void setNString(int parameterIndex, String value) throws SQLException {
+ statement.setNString(parameterIndex, value);
+ }
+
+ public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
+ statement.setNCharacterStream(parameterIndex, value, length);
+ }
+
+ public void setNClob(int parameterIndex, NClob value) throws SQLException {
+ statement.setNClob(parameterIndex, value);
+ }
+
+ public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setClob(parameterIndex, reader, length);
+ }
+
+ public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
+ statement.setBlob(parameterIndex, inputStream, length);
+ }
+
+ public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setNClob(parameterIndex, reader, length);
+ }
+
+ public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
+ statement.setSQLXML(parameterIndex, xmlObject);
+ }
+
+ public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException {
+ statement.setObject(parameterIndex, x, targetSqlType, scaleOrLength);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x, length);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x, length);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader);
+ }
+
+ public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
+ statement.setNCharacterStream(parameterIndex, value);
+ }
+
+ public void setClob(int parameterIndex, Reader reader) throws SQLException {
+ statement.setClob(parameterIndex, reader);
+ }
+
+ public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
+ statement.setBlob(parameterIndex, inputStream);
+ }
+
+ public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+ statement.setNClob(parameterIndex, reader);
+ }
+
+
+ public void close() throws SQLException {
+ sql = "";
+ type = QueryType.UNKNOWN;
+ milli = 0;
+ nano = 0;
+
+ statement.close();
+ }
+
+ public ResultSetMetaData getMetaData() throws SQLException {
+ return statement.getMetaData();
+ }
+
+ public void clearParameters() throws SQLException {
+ statement.clearParameters();
+ }
+
+ public ParameterMetaData getParameterMetaData() throws SQLException {
+ return statement.getParameterMetaData();
+ }
+
+ public void addBatch() throws SQLException {
+ statement.addBatch();
+ }
+
+ public int getMaxFieldSize() throws SQLException {
+ return statement.getMaxFieldSize();
+ }
+
+ public void setMaxFieldSize(int max) throws SQLException {
+ statement.setMaxFieldSize(max);
+ }
+
+ public int getMaxRows() throws SQLException {
+ return statement.getMaxRows();
+ }
+
+ public void setMaxRows(int max) throws SQLException {
+ statement.setMaxRows(max);
+ }
+
+ public void setEscapeProcessing(boolean enable) throws SQLException {
+ statement.setEscapeProcessing(enable);
+ }
+
+ public int getQueryTimeout() throws SQLException {
+ return statement.getQueryTimeout();
+ }
+
+ public void setQueryTimeout(int seconds) throws SQLException {
+ statement.setQueryTimeout(seconds);
+ }
+
+ public void cancel() throws SQLException {
+ statement.cancel();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return statement.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ statement.clearWarnings();
+ }
+
+ public void setCursorName(String name) throws SQLException {
+ statement.setCursorName(name);
+ }
+
+ public boolean execute(String sql) throws SQLException {
+ return statement.execute(sql);
+ }
+
+ public ResultSet getResultSet() throws SQLException {
+ return statement.getResultSet();
+ }
+
+ public int getUpdateCount() throws SQLException {
+ return statement.getUpdateCount();
+ }
+
+ public boolean getMoreResults() throws SQLException {
+ return statement.getMoreResults();
+ }
+
+ public void setFetchDirection(int direction) throws SQLException {
+ statement.setFetchDirection(direction);
+ }
+
+ public int getFetchDirection() throws SQLException {
+ return statement.getFetchDirection();
+ }
+
+ public void setFetchSize(int rows) throws SQLException {
+ statement.setFetchSize(rows);
+ }
+
+ public int getFetchSize() throws SQLException {
+ return statement.getFetchSize();
+ }
+
+ public int getResultSetConcurrency() throws SQLException {
+ return statement.getResultSetConcurrency();
+ }
+
+ public int getResultSetType() throws SQLException {
+ return statement.getResultSetType();
+ }
+
+ public void addBatch(String sql) throws SQLException {
+ statement.addBatch(sql);
+ }
+
+ public void clearBatch() throws SQLException {
+ statement.clearBatch();
+ }
+
+ public int[] executeBatch() throws SQLException {
+ return statement.executeBatch();
+ }
+
+ public Connection getConnection() throws SQLException {
+ return statement.getConnection();
+ }
+
+ public boolean getMoreResults(int current) throws SQLException {
+ return statement.getMoreResults(current);
+ }
+
+ public ResultSet getGeneratedKeys() throws SQLException {
+ return statement.getGeneratedKeys();
+ }
+
+ public int getResultSetHoldability() throws SQLException {
+ return statement.getResultSetHoldability();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return statement.isClosed();
+ }
+
+ public void setPoolable(boolean poolable) throws SQLException {
+ statement.setPoolable(poolable);
+ }
+
+ public boolean isPoolable() throws SQLException {
+ return statement.isPoolable();
+ }
+
+ @Override
+ public void closeOnCompletion() throws SQLException {
+ statement.closeOnCompletion();;
+ }
+
+ @Override
+ public boolean isCloseOnCompletion() throws SQLException {
+ return statement.isCloseOnCompletion();
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return statement.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return statement.isWrapperFor(iface);
+ }
+}
diff --git a/src/nl/astraeus/jdbc/QueryType.java b/src/nl/astraeus/jdbc/QueryType.java
new file mode 100644
index 0000000..744fbfc
--- /dev/null
+++ b/src/nl/astraeus/jdbc/QueryType.java
@@ -0,0 +1,24 @@
+package nl.astraeus.jdbc;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:32:49 PM
+ */
+public enum QueryType {
+ PLAIN("plain"),
+ PREPARED("prepared"),
+ CALLABLE("callable"),
+ UNKNOWN("unknown");
+
+ private String description;
+
+ QueryType(String description) {
+ this.description = description;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+}
diff --git a/src/nl/astraeus/jdbc/example/JdbcStatisticsExample.java b/src/nl/astraeus/jdbc/example/JdbcStatisticsExample.java
new file mode 100644
index 0000000..07aac40
--- /dev/null
+++ b/src/nl/astraeus/jdbc/example/JdbcStatisticsExample.java
@@ -0,0 +1,68 @@
+package nl.astraeus.jdbc.example;
+
+import java.sql.*;
+
+/**
+ * User: rnentjes
+ * Date: 4/12/12
+ * Time: 7:32 PM
+ */
+public class JdbcStatisticsExample {
+
+
+ public static void main(String [] args) throws Exception {
+ Class.forName("org.h2.Driver");
+ Class.forName("nl.astraeus.jdbc.Driver");
+
+ new JdbcStatisticsExample();
+ }
+
+ public JdbcStatisticsExample() throws Exception {
+ Connection conn = DriverManager.getConnection("jdbc:stat:jdbc:h2:mem:test");
+
+ Statement statement = null;
+
+ statement = conn.createStatement();
+ statement.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))");
+ statement.close();
+
+ boolean running = true;
+ int count = 1;
+ PreparedStatement ps = null;
+
+ while (running) {
+ Thread.sleep(10);
+
+ String TableName = "TEST"+(System.nanoTime() % 1000);
+
+ try {
+ ps = conn.prepareStatement("SELECT COUNT(*) FROM "+TableName);
+ ResultSet rs = ps.executeQuery();
+ } catch (SQLException e) {
+ statement = conn.createStatement();
+ statement.execute("CREATE TABLE "+TableName+" (ID INT PRIMARY KEY, NAME VARCHAR(255))");
+ statement.close();
+ } finally {
+ if (ps!=null) {
+ ps.close();
+ }
+ }
+
+ ps = conn.prepareStatement("INSERT INTO "+TableName+" VALUES (?, ?)");
+
+ ps.setInt(1, count++);
+ ps.setString(2, "String "+System.currentTimeMillis());
+
+ ps.execute();
+ ps.close();
+
+ Thread.sleep(10);
+
+ ps = conn.prepareStatement("SELECT * FROM "+TableName);
+ ResultSet rs = ps.executeQuery();
+ statement.close();
+ }
+
+ conn.close();
+ }
+}
diff --git a/src/nl/astraeus/jdbc/util/IOUtils.java b/src/nl/astraeus/jdbc/util/IOUtils.java
new file mode 100644
index 0000000..ce95d9d
--- /dev/null
+++ b/src/nl/astraeus/jdbc/util/IOUtils.java
@@ -0,0 +1,38 @@
+package nl.astraeus.jdbc.util;
+
+import java.io.*;
+
+/**
+ * User: rnentjes
+ * Date: 4/9/12
+ * Time: 2:33 PM
+ */
+public class IOUtils {
+
+ public static String toString(InputStream in) throws IOException {
+ assert in != null;
+
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ StringBuilder buffer = new StringBuilder();
+
+ while(reader.ready()) {
+ buffer.append(reader.readLine());
+ buffer.append("\n");
+ }
+
+ return buffer.toString();
+ } finally {
+ in.close();
+ }
+ }
+
+ public static void copy(InputStream in, OutputStream out) throws IOException {
+ byte [] buffer = new byte[1<<16];
+ int bytes;
+
+ while((bytes = in.read(buffer)) > 0) {
+ out.write(buffer, 0, bytes);
+ }
+ }
+}
diff --git a/src/nl/astraeus/jdbc/util/Util.java b/src/nl/astraeus/jdbc/util/Util.java
new file mode 100644
index 0000000..eaa853b
--- /dev/null
+++ b/src/nl/astraeus/jdbc/util/Util.java
@@ -0,0 +1,25 @@
+package nl.astraeus.jdbc.util;
+
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+
+/**
+ * User: rnentjes
+ * Date: 3/28/12
+ * Time: 12:28 PM
+ */
+public class Util {
+ // utility functions
+ public static String formatNano(long l) {
+ NumberFormat format = new DecimalFormat("###,##0.000000");
+
+ return format.format((double) l / 1000000.0);
+ }
+
+ public static void printMemoryUsage() {
+ System.out.println("Used memory: "+((Runtime.getRuntime().totalMemory() / (1024*1024))-(Runtime.getRuntime().freeMemory() / (1024*1024))));
+ System.out.println("Free memory: "+(Runtime.getRuntime().freeMemory() / (1024*1024)));
+ System.out.println("Total memory: "+(Runtime.getRuntime().totalMemory() / (1024*1024)));
+ System.out.println("Max memory: "+(Runtime.getRuntime().maxMemory() / (1024*1024)));
+ }
+}
diff --git a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java
new file mode 100644
index 0000000..a162d6f
--- /dev/null
+++ b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java
@@ -0,0 +1,90 @@
+package nl.astraeus.jdbc.web;
+
+import nl.astraeus.jdbc.util.IOUtils;
+import nl.astraeus.jdbc.util.Util;
+import nl.astraeus.jdbc.web.page.Menu;
+import nl.astraeus.jdbc.web.page.Page;
+import nl.astraeus.jdbc.web.page.QueryOverview;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+
+/**
+ * User: rnentjes
+ * Date: 3/28/12
+ * Time: 3:05 PM
+ */
+public class JdbcStatisticsServlet extends HttpServlet {
+
+ private String head;
+ private String bottom;
+
+ @Override
+ public void init() throws ServletException {
+ super.init();
+
+ try {
+ head = IOUtils.toString(getClass().getResourceAsStream("head.html"));
+ bottom = IOUtils.toString(getClass().getResourceAsStream("bottom.html"));
+ } catch (IOException e) {
+ throw new ServletException(e);
+ }
+
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ doPost(req, resp);
+ }
+
+ @Override
+ protected void doPost(final HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ long nano = System.nanoTime();
+
+ HttpSession session = req.getSession();
+ boolean ajax = "true".equals(req.getParameter("ajax"));
+
+ resp.setContentType("text/html");
+
+ Page page = (Page)session.getAttribute("page");
+ Page menu = (Page)session.getAttribute("menu");
+
+ session.setMaxInactiveInterval(1800);
+
+ if (menu == null) {
+ menu = new Menu();
+
+ session.setAttribute("menu", menu);
+ }
+
+ if (page == null || "menumain".equals(req.getParameter("action"))) {
+ page = new QueryOverview();
+ } else if ("diagnostics".equals(req.getParameter("action"))) {
+ //page = new Diagnostics();
+ } else {
+ page = page .processRequest(req);
+ }
+
+ menu.processRequest(req);
+
+ session.setAttribute("page", page);
+
+ if (!ajax) {
+ resp.getWriter().print(head);
+ }
+
+ resp.getWriter().print(menu.render(req));
+ resp.getWriter().print(page.render(req));
+
+ if (!ajax) {
+ resp.getWriter().print(bottom);
+ }
+
+ System.out.println("Request ends, time="+ Util.formatNano(System.nanoTime() - nano) +", page="+page.getClass().getSimpleName());
+ }
+
+}
diff --git a/src/nl/astraeus/jdbc/web/ResourceServlet.java b/src/nl/astraeus/jdbc/web/ResourceServlet.java
new file mode 100644
index 0000000..7abfe6f
--- /dev/null
+++ b/src/nl/astraeus/jdbc/web/ResourceServlet.java
@@ -0,0 +1,49 @@
+package nl.astraeus.jdbc.web;
+
+import nl.astraeus.jdbc.util.IOUtils;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * User: rnentjes
+ * Date: 3/28/12
+ * Time: 3:05 PM
+ */
+public class ResourceServlet extends HttpServlet {
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ String uri = req.getRequestURI();
+
+ uri = "nl/astraeus/jdbc/web" + uri;
+ InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(uri);
+
+ if (in == null) {
+ resp.sendError(404, "Cannot find resource '" + uri + "'.");
+ } else {
+ try {
+ if (uri.endsWith("js")) {
+ resp.setContentType("text/javascript");
+ } else if (uri.endsWith("css")) {
+ resp.setContentType("text/css");
+ } else if (uri.endsWith("png")) {
+ resp.setContentType("image/png");
+ } else if (uri.endsWith("jpg")) {
+ resp.setContentType("image/jpeg");
+ } else if (uri.endsWith("gif")) {
+ resp.setContentType("image/gif");
+ }
+
+ IOUtils.copy(in, resp.getOutputStream());
+ } finally {
+ in.close();
+ }
+ }
+ }
+
+}
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..b4ad836
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Simple-jdbc-statistics
\ No newline at end of file
diff --git a/.idea/ant.xml b/.idea/ant.xml
new file mode 100644
index 0000000..2581ca3
--- /dev/null
+++ b/.idea/ant.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..f6eb4e7
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml
new file mode 100644
index 0000000..07e0885
--- /dev/null
+++ b/.idea/libraries/lib.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f403193
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..73ff239
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..275077f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/README b/README
deleted file mode 100644
index 734abaf..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-This file was created by IntelliJ IDEA 11.1.1 for binding GitHub repository
\ No newline at end of file
diff --git a/Simple-jdbc-statistics.iml b/Simple-jdbc-statistics.iml
new file mode 100644
index 0000000..ca90a9b
--- /dev/null
+++ b/Simple-jdbc-statistics.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/h2-1.3.166.jar b/lib/h2-1.3.166.jar
new file mode 100644
index 0000000..4985063
--- /dev/null
+++ b/lib/h2-1.3.166.jar
Binary files differ
diff --git a/lib/servlet-api-2.5.jar b/lib/servlet-api-2.5.jar
new file mode 100644
index 0000000..20b5755
--- /dev/null
+++ b/lib/servlet-api-2.5.jar
Binary files differ
diff --git a/lib/slf4j-api-1.6.4.jar b/lib/slf4j-api-1.6.4.jar
new file mode 100644
index 0000000..4d23f41
--- /dev/null
+++ b/lib/slf4j-api-1.6.4.jar
Binary files differ
diff --git a/lib/slf4j-simple-1.6.4.jar b/lib/slf4j-simple-1.6.4.jar
new file mode 100644
index 0000000..3d1b8d9
--- /dev/null
+++ b/lib/slf4j-simple-1.6.4.jar
Binary files differ
diff --git a/lib/ssr-0.1.jar b/lib/ssr-0.1.jar
new file mode 100644
index 0000000..65dfcf4
--- /dev/null
+++ b/lib/ssr-0.1.jar
Binary files differ
diff --git a/lib/vst-0.4.jar b/lib/vst-0.4.jar
new file mode 100644
index 0000000..db63792
--- /dev/null
+++ b/lib/vst-0.4.jar
Binary files differ
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..ac2dbe1
--- /dev/null
+++ b/readme.md
@@ -0,0 +1 @@
+A simple wrapper around jdbc drivers what will show current jdbc stats of the running queries on a simple web page on port 18080.
\ No newline at end of file
diff --git a/src/nl/astraeus/jdbc/ConnectionLogger.java b/src/nl/astraeus/jdbc/ConnectionLogger.java
new file mode 100644
index 0000000..c3e243f
--- /dev/null
+++ b/src/nl/astraeus/jdbc/ConnectionLogger.java
@@ -0,0 +1,279 @@
+package nl.astraeus.jdbc;
+
+import java.sql.*;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:12:34 PM
+ */
+public class ConnectionLogger implements Connection {
+ private Connection connection;
+
+ private long milli;
+ private long nano;
+ private String lastSql;
+
+ public ConnectionLogger(Connection connection) {
+ this.connection = connection;
+ this.lastSql = "";
+ }
+
+ private void clearTime() {
+ milli = System.currentTimeMillis();
+ nano = System.nanoTime();
+ }
+
+ private void log(String sql) {
+ long m = System.currentTimeMillis() - milli;
+ long n = System.nanoTime() - nano;
+
+ JdbcLogger.log(QueryType.UNKNOWN, sql, m, n);
+ }
+
+ public void commit() throws SQLException {
+ clearTime();
+
+ connection.commit();
+
+ log("commit");
+ }
+
+ public void rollback() throws SQLException {
+ clearTime();
+
+ connection.rollback();
+
+ log("rollback");
+ }
+
+ public void close() throws SQLException {
+ clearTime();
+
+ connection.close();
+
+ log("close");
+ }
+
+ public PreparedStatement prepareStatement(String sql) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, autoGeneratedKeys);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int columnIndexes[]) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, columnIndexes);
+ }
+
+ public PreparedStatement prepareStatement(String sql, String columnNames[]) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, columnNames);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ lastSql = sql;
+ return new PreparedStatementLogger(connection, sql, resultSetType, resultSetConcurrency);
+ }
+
+ public Statement createStatement() throws SQLException {
+ return connection.createStatement();
+ }
+
+ public CallableStatement prepareCall(String sql) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql);
+ }
+
+ public String nativeSQL(String sql) throws SQLException {
+ lastSql = sql;
+ return connection.nativeSQL(sql);
+ }
+
+ public void setAutoCommit(boolean autoCommit) throws SQLException {
+ connection.setAutoCommit(autoCommit);
+ }
+
+ public boolean getAutoCommit() throws SQLException {
+ return connection.getAutoCommit();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return connection.isClosed();
+ }
+
+ public DatabaseMetaData getMetaData() throws SQLException {
+ return connection.getMetaData();
+ }
+
+ public void setReadOnly(boolean readOnly) throws SQLException {
+ connection.setReadOnly(readOnly);
+ }
+
+ public boolean isReadOnly() throws SQLException {
+ return connection.isReadOnly();
+ }
+
+ public void setCatalog(String catalog) throws SQLException {
+ connection.setCatalog(catalog);
+ }
+
+ public String getCatalog() throws SQLException {
+ return connection.getCatalog();
+ }
+
+ public void setTransactionIsolation(int level) throws SQLException {
+ connection.setTransactionIsolation(level);
+ }
+
+ public int getTransactionIsolation() throws SQLException {
+ return connection.getTransactionIsolation();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return connection.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ connection.clearWarnings();
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency);
+ }
+
+ public Map> getTypeMap() throws SQLException {
+ return connection.getTypeMap();
+ }
+
+ public void setTypeMap(Map> map) throws SQLException {
+ connection.setTypeMap(map);
+ }
+
+ public void setHoldability(int holdability) throws SQLException {
+ connection.setHoldability(holdability);
+ }
+
+ public int getHoldability() throws SQLException {
+ return connection.getHoldability();
+ }
+
+ public Savepoint setSavepoint() throws SQLException {
+ return connection.setSavepoint();
+ }
+
+ public Savepoint setSavepoint(String name) throws SQLException {
+ return connection.setSavepoint(name);
+ }
+
+ public void rollback(Savepoint savepoint) throws SQLException {
+ connection.rollback();
+ }
+
+ public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+ connection.releaseSavepoint(savepoint);
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ return connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ lastSql = sql;
+ return connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
+ }
+
+ public Clob createClob() throws SQLException {
+ return connection.createClob();
+ }
+
+ public Blob createBlob() throws SQLException {
+ return connection.createBlob();
+ }
+
+ public NClob createNClob() throws SQLException {
+ return connection.createNClob();
+ }
+
+ public SQLXML createSQLXML() throws SQLException {
+ return connection.createSQLXML();
+ }
+
+ public boolean isValid(int timeout) throws SQLException {
+ return connection.isValid(timeout);
+ }
+
+ public void setClientInfo(String name, String value) throws SQLClientInfoException {
+ connection.setClientInfo(name, value);
+ }
+
+ public void setClientInfo(Properties properties) throws SQLClientInfoException {
+ connection.setClientInfo(properties);
+ }
+
+ public String getClientInfo(String name) throws SQLException {
+ return connection.getClientInfo(name);
+ }
+
+ public Properties getClientInfo() throws SQLException {
+ return connection.getClientInfo();
+ }
+
+ public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
+ return connection.createArrayOf(typeName, elements);
+ }
+
+ public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
+ return connection.createStruct(typeName, attributes);
+ }
+
+ @Override
+ public void setSchema(String schema) throws SQLException {
+ connection.setSchema(schema);
+ }
+
+ @Override
+ public String getSchema() throws SQLException {
+ return connection.getSchema();
+ }
+
+ @Override
+ public void abort(Executor executor) throws SQLException {
+ connection.abort(executor);
+ }
+
+ @Override
+ public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
+ connection.setNetworkTimeout(executor, milliseconds);
+ }
+
+ @Override
+ public int getNetworkTimeout() throws SQLException {
+ return connection.getNetworkTimeout();
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return connection.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return connection.isWrapperFor(iface);
+ }
+}
diff --git a/src/nl/astraeus/jdbc/Driver.java b/src/nl/astraeus/jdbc/Driver.java
new file mode 100644
index 0000000..8317172
--- /dev/null
+++ b/src/nl/astraeus/jdbc/Driver.java
@@ -0,0 +1,116 @@
+package nl.astraeus.jdbc;
+
+import nl.astraeus.http.SimpleWebServer;
+import nl.astraeus.jdbc.web.JdbcStatisticsServlet;
+import nl.astraeus.jdbc.web.ResourceServlet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.*;
+import java.util.Enumeration;
+import java.util.Properties;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:54:37 PM
+ */
+public class Driver implements java.sql.Driver {
+ private final static Logger log = LoggerFactory.getLogger(Driver.class);
+
+ final private static String URL_PREFIX = "jdbc:stat:";
+
+ private java.sql.Driver driver = null;
+ private String[] drivers = {
+ "org.postgresql.Driver",
+ "oracle.jdbc.driver.OracleDriver",
+ "com.sybase.jdbc2.jdbc.SybDriver",
+ "net.sourceforge.jtds.jdbc.Driver",
+ "com.microsoft.jdbc.sqlserver.SQLServerDriver",
+ "com.microsoft.sqlserver.jdbc.SQLServerDriver",
+ "weblogic.jdbc.sqlserver.SQLServerDriver",
+ "com.informix.jdbc.IfxDriver",
+ "org.apache.derby.jdbc.ClientDriver",
+ "org.apache.derby.jdbc.EmbeddedDriver",
+ "com.mysql.jdbc.Driver",
+ "org.hsqldb.jdbcDriver",
+ "org.h2.Driver" };
+
+ static {
+ log.debug("Loading driver class " + Driver.class.getName());
+
+ try {
+ DriverManager.registerDriver(new Driver());
+ } catch (SQLException e) {
+ log.error("", e);
+ }
+ }
+
+ public Driver() {
+ for (String dr : drivers) {
+ try {
+ Class.forName(dr);
+ } catch (Throwable e) {
+ log.debug("Can't instantiate driver: " + dr, e);
+ }
+ }
+ }
+
+ private java.sql.Driver findDriver(String url) throws SQLException {
+ Enumeration e = DriverManager.getDrivers();
+
+ while (e.hasMoreElements()) {
+ java.sql.Driver d = (java.sql.Driver) e.nextElement();
+
+ if (d.acceptsURL(url)) {
+ return d;
+ }
+ }
+
+ throw new SQLException("Driver not found: " + url);
+ }
+
+ public Connection connect(String url, Properties info) throws SQLException {
+ url = url.substring(URL_PREFIX.length());
+
+ if (driver == null) {
+ driver = findDriver(url);
+ }
+
+ if (driver != null) {
+ SimpleWebServer server = new SimpleWebServer(18080);
+
+ server.addServlet(new JdbcStatisticsServlet(), "/");
+ server.addServlet(new ResourceServlet(), "/resources/*");
+
+ server.start();
+ }
+
+ return new ConnectionLogger(driver.connect(url, info));
+ }
+
+ public boolean acceptsURL(String url) throws SQLException {
+ return (url != null && url.startsWith(URL_PREFIX));
+ }
+
+ public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
+ return driver.getPropertyInfo(url, info);
+ }
+
+ public int getMajorVersion() {
+ return driver.getMajorVersion();
+ }
+
+ public int getMinorVersion() {
+ return driver.getMinorVersion();
+ }
+
+ public boolean jdbcCompliant() {
+ return driver.jdbcCompliant();
+ }
+
+ @Override
+ public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ return driver.getParentLogger();
+ }
+}
diff --git a/src/nl/astraeus/jdbc/JdbcLogger.java b/src/nl/astraeus/jdbc/JdbcLogger.java
new file mode 100644
index 0000000..f4bc125
--- /dev/null
+++ b/src/nl/astraeus/jdbc/JdbcLogger.java
@@ -0,0 +1,113 @@
+package nl.astraeus.jdbc;
+
+import nl.astraeus.jdbc.util.Util;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * User: riennentjes
+ * Date: Jul 12, 2008
+ * Time: 9:15:21 AM
+ */
+public class JdbcLogger {
+ private final static Logger logger = LoggerFactory.getLogger(JdbcLogger.class);
+
+ private final static JdbcLogger instance = new JdbcLogger();
+
+ public static JdbcLogger get() {
+ return instance;
+ }
+
+ public final static class LogEntry {
+ public QueryType type;
+ public String sql;
+ public long milli;
+ public long nano;
+ public int count;
+ public int hash;
+
+ public LogEntry(int hash, QueryType type, String sql, long milli, long nano) {
+ this.hash = hash;
+ this.type = type;
+ this.sql = sql;
+ this.milli = milli;
+ this.nano = nano;
+ this.count = 1;
+ }
+
+ public void addCount(long milli, long nano) {
+ synchronized (this) {
+ count++;
+ this.milli += milli;
+ this.nano += nano;
+ }
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public String getMilli() {
+ return Util.formatNano(milli*1000000/count);
+ }
+
+ public String getNano() {
+ return Util.formatNano(nano/count);
+ }
+
+ public String getTotal() {
+ return Util.formatNano(nano);
+ }
+
+ public String getSql() {
+ return sql;
+ }
+ }
+
+ private Map queries;
+
+ public JdbcLogger() {
+ queries = new ConcurrentHashMap();
+ }
+
+ public void logEntry(QueryType type, String sql, long milli, long nano) {
+ int hash = sql.hashCode();
+ LogEntry entry = queries.get(hash);
+
+ if (entry == null) {
+ entry = new LogEntry(hash, type, sql, milli, nano);
+ queries.put(hash, entry);
+ } else {
+ entry.addCount(milli, nano);
+ }
+
+ if (queries.size() > 1000) {
+ List toRemove = new LinkedList();
+ List values = new LinkedList(queries.values());
+
+ Collections.sort(values, new Comparator() {
+ @Override
+ public int compare(LogEntry o1, LogEntry o2) {
+ return o1.count - o2.count;
+ }
+ });
+
+ while (queries.size() > 900) {
+ queries.remove(values.remove(0).hash);
+
+ }
+ }
+ }
+
+ public static void log(QueryType type, String sql, long milli, long nano) {
+ instance.logEntry(type, sql, milli, nano);
+ }
+
+ public Collection getEntries() {
+ return queries.values();
+ }
+
+}
diff --git a/src/nl/astraeus/jdbc/PreparedStatementLogger.java b/src/nl/astraeus/jdbc/PreparedStatementLogger.java
new file mode 100644
index 0000000..98aefc7
--- /dev/null
+++ b/src/nl/astraeus/jdbc/PreparedStatementLogger.java
@@ -0,0 +1,577 @@
+package nl.astraeus.jdbc;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.*;
+import java.util.Calendar;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 7:47:57 PM
+ */
+public class PreparedStatementLogger implements PreparedStatement {
+ private final static Logger log = LoggerFactory.getLogger(PreparedStatementLogger.class);
+
+ private PreparedStatement statement;
+
+ private String sql;
+ private QueryType type;
+ private long milli;
+ private long nano;
+
+ //private ArrayList parameters;
+
+ public PreparedStatementLogger(PreparedStatement statement) {
+ this.statement = statement;
+ this.sql = "";
+ this.type = QueryType.UNKNOWN;
+ }
+
+ private void clearTime() {
+ milli = System.currentTimeMillis();
+ nano = System.nanoTime();
+ }
+
+ private void log(QueryType type, String sql) {
+ long m = System.currentTimeMillis() - milli;
+ long n = System.nanoTime() - nano;
+
+ JdbcLogger.log(type, sql, m, n);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, resultSetType, resultSetConcurrency);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, autoGeneratedKeys);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, int[] columnIndexes) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, columnIndexes);
+ }
+
+ public PreparedStatementLogger(Connection connection, String sql, String[] columnNames) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PREPARED;
+ clearTime();
+ statement = connection.prepareStatement(sql, columnNames);
+ }
+
+ public boolean execute() throws SQLException {
+ clearTime();
+
+ boolean result = statement.execute();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public ResultSet executeQuery() throws SQLException {
+ clearTime();
+
+ ResultSet result = statement.executeQuery();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate() throws SQLException {
+ clearTime();
+
+ int result = statement.executeUpdate();
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public ResultSet executeQuery(String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ ResultSet result = statement.executeQuery(sql);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, autoGeneratedKeys);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, int columnIndexes[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, columnIndexes);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public int executeUpdate(String sql, String columnNames[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ int result = statement.executeUpdate(sql, columnNames);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, autoGeneratedKeys);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, int columnIndexes[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, columnIndexes);
+
+ log(type, sql);
+
+ return result;
+ }
+
+ public boolean execute(String sql, String columnNames[]) throws SQLException {
+ this.sql = sql;
+ this.type = QueryType.PLAIN;
+
+ clearTime();
+
+ boolean result = statement.execute(sql, columnNames);
+
+ log(type, sql);
+
+ return result;
+ }
+
+
+ public void setNull(int parameterIndex, int sqlType) throws SQLException {
+ statement.setNull(parameterIndex, sqlType);
+ }
+
+ public void setBoolean(int parameterIndex, boolean x) throws SQLException {
+ statement.setBoolean(parameterIndex, x);
+ }
+
+ public void setByte(int parameterIndex, byte x) throws SQLException {
+ statement.setByte(parameterIndex, x);
+ }
+
+ public void setShort(int parameterIndex, short x) throws SQLException {
+ statement.setShort(parameterIndex, x);
+ }
+
+ public void setInt(int parameterIndex, int x) throws SQLException {
+ statement.setInt(parameterIndex, x);
+ }
+
+ public void setLong(int parameterIndex, long x) throws SQLException {
+ statement.setLong(parameterIndex, x);
+ }
+
+ public void setFloat(int parameterIndex, float x) throws SQLException {
+ statement.setFloat(parameterIndex, x);
+ }
+
+ public void setDouble(int parameterIndex, double x) throws SQLException {
+ statement.setDouble(parameterIndex, x);
+ }
+
+ public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
+ statement.setBigDecimal(parameterIndex, x);
+ }
+
+ public void setString(int parameterIndex, String x) throws SQLException {
+ statement.setString(parameterIndex, x);
+ }
+
+ public void setBytes(int parameterIndex, byte x[]) throws SQLException {
+ statement.setBytes(parameterIndex, x);
+ }
+
+ public void setDate(int parameterIndex, Date x) throws SQLException {
+ statement.setDate(parameterIndex, x);
+ }
+
+ public void setTime(int parameterIndex, Time x) throws SQLException {
+ statement.setTime(parameterIndex, x);
+ }
+
+ public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
+ statement.setTimestamp(parameterIndex, x);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x, length);
+ }
+
+ public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setUnicodeStream(parameterIndex, x, length);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x, length);
+ }
+
+ public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
+ statement.setObject(parameterIndex, x, targetSqlType);
+ }
+
+ public void setObject(int parameterIndex, Object x) throws SQLException {
+ statement.setObject(parameterIndex, x);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ public void setRef(int parameterIndex, Ref x) throws SQLException {
+ statement.setRef(parameterIndex, x);
+ }
+
+ public void setBlob(int parameterIndex, Blob x) throws SQLException {
+ statement.setBlob(parameterIndex, x);
+ }
+
+ public void setClob(int parameterIndex, Clob x) throws SQLException {
+ statement.setClob(parameterIndex, x);
+ }
+
+ public void setArray(int parameterIndex, Array x) throws SQLException {
+ statement.setArray(parameterIndex, x);
+ }
+
+ public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
+ statement.setDate(parameterIndex, x, cal);
+ }
+
+ public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
+ statement.setTime(parameterIndex, x, cal);
+ }
+
+ public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
+ statement.setTimestamp(parameterIndex, x, cal);
+ }
+
+ public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
+ statement.setNull(parameterIndex, sqlType, typeName);
+ }
+
+ public void setURL(int parameterIndex, URL x) throws SQLException {
+ statement.setURL(parameterIndex, x);
+ }
+
+ public void setRowId(int parameterIndex, RowId x) throws SQLException {
+ statement.setRowId(parameterIndex, x);
+ }
+
+ public void setNString(int parameterIndex, String value) throws SQLException {
+ statement.setNString(parameterIndex, value);
+ }
+
+ public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
+ statement.setNCharacterStream(parameterIndex, value, length);
+ }
+
+ public void setNClob(int parameterIndex, NClob value) throws SQLException {
+ statement.setNClob(parameterIndex, value);
+ }
+
+ public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setClob(parameterIndex, reader, length);
+ }
+
+ public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
+ statement.setBlob(parameterIndex, inputStream, length);
+ }
+
+ public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setNClob(parameterIndex, reader, length);
+ }
+
+ public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
+ statement.setSQLXML(parameterIndex, xmlObject);
+ }
+
+ public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException {
+ statement.setObject(parameterIndex, x, targetSqlType, scaleOrLength);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x, length);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x, length);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
+ statement.setAsciiStream(parameterIndex, x);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
+ statement.setBinaryStream(parameterIndex, x);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
+ statement.setCharacterStream(parameterIndex, reader);
+ }
+
+ public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
+ statement.setNCharacterStream(parameterIndex, value);
+ }
+
+ public void setClob(int parameterIndex, Reader reader) throws SQLException {
+ statement.setClob(parameterIndex, reader);
+ }
+
+ public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
+ statement.setBlob(parameterIndex, inputStream);
+ }
+
+ public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+ statement.setNClob(parameterIndex, reader);
+ }
+
+
+ public void close() throws SQLException {
+ sql = "";
+ type = QueryType.UNKNOWN;
+ milli = 0;
+ nano = 0;
+
+ statement.close();
+ }
+
+ public ResultSetMetaData getMetaData() throws SQLException {
+ return statement.getMetaData();
+ }
+
+ public void clearParameters() throws SQLException {
+ statement.clearParameters();
+ }
+
+ public ParameterMetaData getParameterMetaData() throws SQLException {
+ return statement.getParameterMetaData();
+ }
+
+ public void addBatch() throws SQLException {
+ statement.addBatch();
+ }
+
+ public int getMaxFieldSize() throws SQLException {
+ return statement.getMaxFieldSize();
+ }
+
+ public void setMaxFieldSize(int max) throws SQLException {
+ statement.setMaxFieldSize(max);
+ }
+
+ public int getMaxRows() throws SQLException {
+ return statement.getMaxRows();
+ }
+
+ public void setMaxRows(int max) throws SQLException {
+ statement.setMaxRows(max);
+ }
+
+ public void setEscapeProcessing(boolean enable) throws SQLException {
+ statement.setEscapeProcessing(enable);
+ }
+
+ public int getQueryTimeout() throws SQLException {
+ return statement.getQueryTimeout();
+ }
+
+ public void setQueryTimeout(int seconds) throws SQLException {
+ statement.setQueryTimeout(seconds);
+ }
+
+ public void cancel() throws SQLException {
+ statement.cancel();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return statement.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ statement.clearWarnings();
+ }
+
+ public void setCursorName(String name) throws SQLException {
+ statement.setCursorName(name);
+ }
+
+ public boolean execute(String sql) throws SQLException {
+ return statement.execute(sql);
+ }
+
+ public ResultSet getResultSet() throws SQLException {
+ return statement.getResultSet();
+ }
+
+ public int getUpdateCount() throws SQLException {
+ return statement.getUpdateCount();
+ }
+
+ public boolean getMoreResults() throws SQLException {
+ return statement.getMoreResults();
+ }
+
+ public void setFetchDirection(int direction) throws SQLException {
+ statement.setFetchDirection(direction);
+ }
+
+ public int getFetchDirection() throws SQLException {
+ return statement.getFetchDirection();
+ }
+
+ public void setFetchSize(int rows) throws SQLException {
+ statement.setFetchSize(rows);
+ }
+
+ public int getFetchSize() throws SQLException {
+ return statement.getFetchSize();
+ }
+
+ public int getResultSetConcurrency() throws SQLException {
+ return statement.getResultSetConcurrency();
+ }
+
+ public int getResultSetType() throws SQLException {
+ return statement.getResultSetType();
+ }
+
+ public void addBatch(String sql) throws SQLException {
+ statement.addBatch(sql);
+ }
+
+ public void clearBatch() throws SQLException {
+ statement.clearBatch();
+ }
+
+ public int[] executeBatch() throws SQLException {
+ return statement.executeBatch();
+ }
+
+ public Connection getConnection() throws SQLException {
+ return statement.getConnection();
+ }
+
+ public boolean getMoreResults(int current) throws SQLException {
+ return statement.getMoreResults(current);
+ }
+
+ public ResultSet getGeneratedKeys() throws SQLException {
+ return statement.getGeneratedKeys();
+ }
+
+ public int getResultSetHoldability() throws SQLException {
+ return statement.getResultSetHoldability();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return statement.isClosed();
+ }
+
+ public void setPoolable(boolean poolable) throws SQLException {
+ statement.setPoolable(poolable);
+ }
+
+ public boolean isPoolable() throws SQLException {
+ return statement.isPoolable();
+ }
+
+ @Override
+ public void closeOnCompletion() throws SQLException {
+ statement.closeOnCompletion();;
+ }
+
+ @Override
+ public boolean isCloseOnCompletion() throws SQLException {
+ return statement.isCloseOnCompletion();
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return statement.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return statement.isWrapperFor(iface);
+ }
+}
diff --git a/src/nl/astraeus/jdbc/QueryType.java b/src/nl/astraeus/jdbc/QueryType.java
new file mode 100644
index 0000000..744fbfc
--- /dev/null
+++ b/src/nl/astraeus/jdbc/QueryType.java
@@ -0,0 +1,24 @@
+package nl.astraeus.jdbc;
+
+/**
+ * User: riennentjes
+ * Date: Jul 10, 2008
+ * Time: 8:32:49 PM
+ */
+public enum QueryType {
+ PLAIN("plain"),
+ PREPARED("prepared"),
+ CALLABLE("callable"),
+ UNKNOWN("unknown");
+
+ private String description;
+
+ QueryType(String description) {
+ this.description = description;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+}
diff --git a/src/nl/astraeus/jdbc/example/JdbcStatisticsExample.java b/src/nl/astraeus/jdbc/example/JdbcStatisticsExample.java
new file mode 100644
index 0000000..07aac40
--- /dev/null
+++ b/src/nl/astraeus/jdbc/example/JdbcStatisticsExample.java
@@ -0,0 +1,68 @@
+package nl.astraeus.jdbc.example;
+
+import java.sql.*;
+
+/**
+ * User: rnentjes
+ * Date: 4/12/12
+ * Time: 7:32 PM
+ */
+public class JdbcStatisticsExample {
+
+
+ public static void main(String [] args) throws Exception {
+ Class.forName("org.h2.Driver");
+ Class.forName("nl.astraeus.jdbc.Driver");
+
+ new JdbcStatisticsExample();
+ }
+
+ public JdbcStatisticsExample() throws Exception {
+ Connection conn = DriverManager.getConnection("jdbc:stat:jdbc:h2:mem:test");
+
+ Statement statement = null;
+
+ statement = conn.createStatement();
+ statement.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))");
+ statement.close();
+
+ boolean running = true;
+ int count = 1;
+ PreparedStatement ps = null;
+
+ while (running) {
+ Thread.sleep(10);
+
+ String TableName = "TEST"+(System.nanoTime() % 1000);
+
+ try {
+ ps = conn.prepareStatement("SELECT COUNT(*) FROM "+TableName);
+ ResultSet rs = ps.executeQuery();
+ } catch (SQLException e) {
+ statement = conn.createStatement();
+ statement.execute("CREATE TABLE "+TableName+" (ID INT PRIMARY KEY, NAME VARCHAR(255))");
+ statement.close();
+ } finally {
+ if (ps!=null) {
+ ps.close();
+ }
+ }
+
+ ps = conn.prepareStatement("INSERT INTO "+TableName+" VALUES (?, ?)");
+
+ ps.setInt(1, count++);
+ ps.setString(2, "String "+System.currentTimeMillis());
+
+ ps.execute();
+ ps.close();
+
+ Thread.sleep(10);
+
+ ps = conn.prepareStatement("SELECT * FROM "+TableName);
+ ResultSet rs = ps.executeQuery();
+ statement.close();
+ }
+
+ conn.close();
+ }
+}
diff --git a/src/nl/astraeus/jdbc/util/IOUtils.java b/src/nl/astraeus/jdbc/util/IOUtils.java
new file mode 100644
index 0000000..ce95d9d
--- /dev/null
+++ b/src/nl/astraeus/jdbc/util/IOUtils.java
@@ -0,0 +1,38 @@
+package nl.astraeus.jdbc.util;
+
+import java.io.*;
+
+/**
+ * User: rnentjes
+ * Date: 4/9/12
+ * Time: 2:33 PM
+ */
+public class IOUtils {
+
+ public static String toString(InputStream in) throws IOException {
+ assert in != null;
+
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ StringBuilder buffer = new StringBuilder();
+
+ while(reader.ready()) {
+ buffer.append(reader.readLine());
+ buffer.append("\n");
+ }
+
+ return buffer.toString();
+ } finally {
+ in.close();
+ }
+ }
+
+ public static void copy(InputStream in, OutputStream out) throws IOException {
+ byte [] buffer = new byte[1<<16];
+ int bytes;
+
+ while((bytes = in.read(buffer)) > 0) {
+ out.write(buffer, 0, bytes);
+ }
+ }
+}
diff --git a/src/nl/astraeus/jdbc/util/Util.java b/src/nl/astraeus/jdbc/util/Util.java
new file mode 100644
index 0000000..eaa853b
--- /dev/null
+++ b/src/nl/astraeus/jdbc/util/Util.java
@@ -0,0 +1,25 @@
+package nl.astraeus.jdbc.util;
+
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+
+/**
+ * User: rnentjes
+ * Date: 3/28/12
+ * Time: 12:28 PM
+ */
+public class Util {
+ // utility functions
+ public static String formatNano(long l) {
+ NumberFormat format = new DecimalFormat("###,##0.000000");
+
+ return format.format((double) l / 1000000.0);
+ }
+
+ public static void printMemoryUsage() {
+ System.out.println("Used memory: "+((Runtime.getRuntime().totalMemory() / (1024*1024))-(Runtime.getRuntime().freeMemory() / (1024*1024))));
+ System.out.println("Free memory: "+(Runtime.getRuntime().freeMemory() / (1024*1024)));
+ System.out.println("Total memory: "+(Runtime.getRuntime().totalMemory() / (1024*1024)));
+ System.out.println("Max memory: "+(Runtime.getRuntime().maxMemory() / (1024*1024)));
+ }
+}
diff --git a/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java
new file mode 100644
index 0000000..a162d6f
--- /dev/null
+++ b/src/nl/astraeus/jdbc/web/JdbcStatisticsServlet.java
@@ -0,0 +1,90 @@
+package nl.astraeus.jdbc.web;
+
+import nl.astraeus.jdbc.util.IOUtils;
+import nl.astraeus.jdbc.util.Util;
+import nl.astraeus.jdbc.web.page.Menu;
+import nl.astraeus.jdbc.web.page.Page;
+import nl.astraeus.jdbc.web.page.QueryOverview;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+
+/**
+ * User: rnentjes
+ * Date: 3/28/12
+ * Time: 3:05 PM
+ */
+public class JdbcStatisticsServlet extends HttpServlet {
+
+ private String head;
+ private String bottom;
+
+ @Override
+ public void init() throws ServletException {
+ super.init();
+
+ try {
+ head = IOUtils.toString(getClass().getResourceAsStream("head.html"));
+ bottom = IOUtils.toString(getClass().getResourceAsStream("bottom.html"));
+ } catch (IOException e) {
+ throw new ServletException(e);
+ }
+
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ doPost(req, resp);
+ }
+
+ @Override
+ protected void doPost(final HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ long nano = System.nanoTime();
+
+ HttpSession session = req.getSession();
+ boolean ajax = "true".equals(req.getParameter("ajax"));
+
+ resp.setContentType("text/html");
+
+ Page page = (Page)session.getAttribute("page");
+ Page menu = (Page)session.getAttribute("menu");
+
+ session.setMaxInactiveInterval(1800);
+
+ if (menu == null) {
+ menu = new Menu();
+
+ session.setAttribute("menu", menu);
+ }
+
+ if (page == null || "menumain".equals(req.getParameter("action"))) {
+ page = new QueryOverview();
+ } else if ("diagnostics".equals(req.getParameter("action"))) {
+ //page = new Diagnostics();
+ } else {
+ page = page .processRequest(req);
+ }
+
+ menu.processRequest(req);
+
+ session.setAttribute("page", page);
+
+ if (!ajax) {
+ resp.getWriter().print(head);
+ }
+
+ resp.getWriter().print(menu.render(req));
+ resp.getWriter().print(page.render(req));
+
+ if (!ajax) {
+ resp.getWriter().print(bottom);
+ }
+
+ System.out.println("Request ends, time="+ Util.formatNano(System.nanoTime() - nano) +", page="+page.getClass().getSimpleName());
+ }
+
+}
diff --git a/src/nl/astraeus/jdbc/web/ResourceServlet.java b/src/nl/astraeus/jdbc/web/ResourceServlet.java
new file mode 100644
index 0000000..7abfe6f
--- /dev/null
+++ b/src/nl/astraeus/jdbc/web/ResourceServlet.java
@@ -0,0 +1,49 @@
+package nl.astraeus.jdbc.web;
+
+import nl.astraeus.jdbc.util.IOUtils;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * User: rnentjes
+ * Date: 3/28/12
+ * Time: 3:05 PM
+ */
+public class ResourceServlet extends HttpServlet {
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ String uri = req.getRequestURI();
+
+ uri = "nl/astraeus/jdbc/web" + uri;
+ InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(uri);
+
+ if (in == null) {
+ resp.sendError(404, "Cannot find resource '" + uri + "'.");
+ } else {
+ try {
+ if (uri.endsWith("js")) {
+ resp.setContentType("text/javascript");
+ } else if (uri.endsWith("css")) {
+ resp.setContentType("text/css");
+ } else if (uri.endsWith("png")) {
+ resp.setContentType("image/png");
+ } else if (uri.endsWith("jpg")) {
+ resp.setContentType("image/jpeg");
+ } else if (uri.endsWith("gif")) {
+ resp.setContentType("image/gif");
+ }
+
+ IOUtils.copy(in, resp.getOutputStream());
+ } finally {
+ in.close();
+ }
+ }
+ }
+
+}
diff --git a/src/nl/astraeus/jdbc/web/bottom.html b/src/nl/astraeus/jdbc/web/bottom.html
new file mode 100644
index 0000000..1288de4
--- /dev/null
+++ b/src/nl/astraeus/jdbc/web/bottom.html
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+