@ -6,12 +6,8 @@ import org.xbib.jdbc.query.util.Metric;
import javax.sql.DataSource ;
import java.io.Closeable ;
import java.io.FileInputStream ;
import java.io.IOException ;
import java.io.InputStreamReader ;
import java.lang.reflect.InvocationTargetException ;
import java.nio.charset.Charset ;
import java.nio.charset.CharsetDecoder ;
import java.sql.Connection ;
import java.sql.DriverManager ;
import java.sql.SQLException ;
@ -30,7 +26,7 @@ import java.util.logging.Logger;
* /
public final class DatabaseProvider implements Supplier < Database > , Closeable {
private static final Logger log = Logger . getLogger ( DatabaseProvider . class . getName ( ) ) ;
private static final Logger log ger = Logger . getLogger ( DatabaseProvider . class . getName ( ) ) ;
private static final AtomicInteger poolNameCounter = new AtomicInteger ( 1 ) ;
@ -63,7 +59,8 @@ public final class DatabaseProvider implements Supplier<Database>, Closeable {
*
* < p > A database pool will be created using jdbc - connection - pool . < / p >
* /
public static DatabaseProviderBuilder builder ( Config config ) throws ClassNotFoundException , InvocationTargetException , NoSuchMethodException , InstantiationException , IllegalAccessException {
public static DatabaseProviderBuilder builder ( Config config )
throws ClassNotFoundException , InvocationTargetException , NoSuchMethodException , InstantiationException , IllegalAccessException {
return builder ( createDataSource ( config ) , getFlavor ( config ) ) ;
}
@ -85,67 +82,12 @@ public final class DatabaseProvider implements Supplier<Database>, Closeable {
* the JDBC standard DriverManager method . The url parameter will be inspected
* to determine the Flavor for this database .
* /
public static DatabaseProviderBuilder builder ( String url ) {
return builder ( url, Flavor . fromJdbcUrl ( url ) , null , null , null ) ;
public static DatabaseProviderBuilder builder ( ClassLoader classLoader , String url ) {
return builder ( classLoader, url, Flavor . fromJdbcUrl ( url ) , null , null , null ) ;
}
/ * *
* Builder method to create and initialize an instance of this class using
* the JDBC standard DriverManager method .
*
* @param flavor use this flavor rather than guessing based on the url
* /
public static DatabaseProviderBuilder builder ( String url , Flavor flavor ) {
return builder ( url , flavor , null , null , null ) ;
}
/ * *
* Builder method to create and initialize an instance of this class using
* the JDBC standard DriverManager method . The url parameter will be inspected
* to determine the Flavor for this database .
* /
public static DatabaseProviderBuilder builder ( String url , Properties info ) {
return builder ( url , Flavor . fromJdbcUrl ( url ) , info , null , null ) ;
}
/ * *
* Builder method to create and initialize an instance of this class using
* the JDBC standard DriverManager method .
*
* @param flavor use this flavor rather than guessing based on the url
* /
public static DatabaseProviderBuilder builder ( String url , Flavor flavor , Properties info ) {
return builder ( url , flavor , info , null , null ) ;
}
/ * *
* Builder method to create and initialize an instance of this class using
* the JDBC standard DriverManager method . The url parameter will be inspected
* to determine the Flavor for this database .
* /
public static DatabaseProviderBuilder builder ( String url , String user , String password ) {
return builder ( url , Flavor . fromJdbcUrl ( url ) , null , user , password ) ;
}
/ * *
* Builder method to create and initialize an instance of this class using
* the JDBC standard DriverManager method .
*
* @param flavor use this flavor rather than guessing based on the url
* /
public static DatabaseProviderBuilder builder ( String url ,
Flavor flavor ,
String user ,
String password ) {
return builder ( url , flavor , null , user , password ) ;
}
private static DatabaseProviderBuilder builder ( String url ,
private static DatabaseProviderBuilder builder ( ClassLoader classLoader ,
String url ,
Flavor flavor ,
Properties info ,
String user ,
@ -156,7 +98,7 @@ public final class DatabaseProvider implements Supplier<Database>, Closeable {
} catch ( SQLException e ) {
if ( flavor . driverClass ( ) ! = null ) {
try {
Class . forName ( flavor . driverClass ( ) );
Class . forName ( flavor . driverClass ( ) , true , classLoader );
} catch ( ClassNotFoundException e1 ) {
throw new DatabaseException ( "couldn't locate JDBC driver" , e1 ) ;
}
@ -176,417 +118,6 @@ public final class DatabaseProvider implements Supplier<Database>, Closeable {
} , options ) ;
}
/ * *
* Configure the database from up to five properties read from a file :
* < pre >
* database . url = . . . Database connect string ( required )
* database . user = . . . Authenticate as this user ( optional if provided in url )
* database . password = . . . User password ( optional if user and password provided in
* url ; prompted on standard input if user is provided and
* password is not )
* database . flavor = . . . What kind of database it is ( optional , will guess based
* on the url if this is not provided )
* database . driver = . . . The Java class of the JDBC driver to load ( optional , will
* guess based on the flavor if this is not provided )
* < / pre >
* < p > This will use the JVM default character encoding to read the property file . < / p >
*
* @param propertyFileName path to the properties file we will attempt to read
* @throws DatabaseException if the property file could not be read for any reason
* /
public static DatabaseProviderBuilder fromPropertyFile ( String propertyFileName ) {
return fromPropertyFile ( propertyFileName , Charset . defaultCharset ( ) . newDecoder ( ) ) ;
}
/ * *
* Configure the database from up to five properties read from a file :
* < pre >
* database . url = . . . Database connect string ( required )
* database . user = . . . Authenticate as this user ( optional if provided in url )
* database . password = . . . User password ( optional if user and password provided in
* url ; prompted on standard input if user is provided and
* password is not )
* database . flavor = . . . What kind of database it is ( optional , will guess based
* on the url if this is not provided )
* database . driver = . . . The Java class of the JDBC driver to load ( optional , will
* guess based on the flavor if this is not provided )
* < / pre >
*
* @param propertyFileName path to the properties file we will attempt to read
* @param decoder character encoding to use when reading the property file
* @throws DatabaseException if the property file could not be read for any reason
* /
public static DatabaseProviderBuilder fromPropertyFile ( String propertyFileName , CharsetDecoder decoder ) {
Properties properties = new Properties ( ) ;
if ( propertyFileName ! = null & & propertyFileName . length ( ) > 0 ) {
try (
FileInputStream fis = new FileInputStream ( propertyFileName ) ;
InputStreamReader reader = new InputStreamReader ( fis , decoder )
) {
properties . load ( reader ) ;
} catch ( Exception e ) {
throw new DatabaseException ( "Unable to read properties file: " + propertyFileName , e ) ;
}
}
return fromProperties ( properties , "" , true ) ;
}
/ * *
* Configure the database from up to five properties read from a file :
* < pre >
* database . url = . . . Database connect string ( required )
* database . user = . . . Authenticate as this user ( optional if provided in url )
* database . password = . . . User password ( optional if user and password provided in
* url ; prompted on standard input if user is provided and
* password is not )
* database . flavor = . . . What kind of database it is ( optional , will guess based
* on the url if this is not provided )
* database . driver = . . . The Java class of the JDBC driver to load ( optional , will
* guess based on the flavor if this is not provided )
* < / pre >
* < p > This will use the JVM default character encoding to read the property file . < / p >
*
* @param filename path to the properties file we will attempt to read
* @param propertyPrefix if this is null or empty the properties above will be read ;
* if a value is provided it will be prefixed to each property
* ( exactly , so if you want to use "my.database.url" you must
* pass "my." as the prefix )
* @throws DatabaseException if the property file could not be read for any reason
* /
public static DatabaseProviderBuilder fromPropertyFile ( String filename , String propertyPrefix ) {
return fromPropertyFile ( filename , propertyPrefix , Charset . defaultCharset ( ) . newDecoder ( ) ) ;
}
/ * *
* Configure the database from up to five properties read from a file :
* < pre >
* database . url = . . . Database connect string ( required )
* database . user = . . . Authenticate as this user ( optional if provided in url )
* database . password = . . . User password ( optional if user and password provided in
* url ; prompted on standard input if user is provided and
* password is not )
* database . flavor = . . . What kind of database it is ( optional , will guess based
* on the url if this is not provided )
* database . driver = . . . The Java class of the JDBC driver to load ( optional , will
* guess based on the flavor if this is not provided )
* < / pre >
*
* @param filename path to the properties file we will attempt to read
* @param propertyPrefix if this is null or empty the properties above will be read ;
* if a value is provided it will be prefixed to each property
* ( exactly , so if you want to use "my.database.url" you must
* pass "my." as the prefix )
* @param decoder character encoding to use when reading the property file
* @throws DatabaseException if the property file could not be read for any reason
* /
public static DatabaseProviderBuilder fromPropertyFile ( String filename , String propertyPrefix , CharsetDecoder decoder ) {
Properties properties = new Properties ( ) ;
if ( filename ! = null & & filename . length ( ) > 0 ) {
try (
FileInputStream fis = new FileInputStream ( filename ) ;
InputStreamReader reader = new InputStreamReader ( fis , decoder )
) {
properties . load ( reader ) ;
} catch ( Exception e ) {
throw new DatabaseException ( "Unable to read properties file: " + filename , e ) ;
}
}
return fromProperties ( properties , propertyPrefix , true ) ;
}
/ * *
* Configure the database from up to five properties read from the provided properties :
* < pre >
* database . url = . . . Database connect string ( required )
* database . user = . . . Authenticate as this user ( optional if provided in url )
* database . password = . . . User password ( optional if user and password provided in
* url ; prompted on standard input if user is provided and
* password is not )
* database . flavor = . . . What kind of database it is ( optional , will guess based
* on the url if this is not provided )
* database . driver = . . . The Java class of the JDBC driver to load ( optional , will
* guess based on the flavor if this is not provided )
* < / pre >
*
* @param properties properties will be read from here
* @throws DatabaseException if the property file could not be read for any reason
* /
public static DatabaseProviderBuilder fromProperties ( Properties properties ) {
return fromProperties ( properties , "" , false ) ;
}
/ * *
* Configure the database from up to five properties read from the provided properties :
* < pre >
* database . url = . . . Database connect string ( required )
* database . user = . . . Authenticate as this user ( optional if provided in url )
* database . password = . . . User password ( optional if user and password provided in
* url ; prompted on standard input if user is provided and
* password is not )
* database . flavor = . . . What kind of database it is ( optional , will guess based
* on the url if this is not provided )
* database . driver = . . . The Java class of the JDBC driver to load ( optional , will
* guess based on the flavor if this is not provided )
* < / pre >
*
* @param properties properties will be read from here
* @param propertyPrefix if this is null or empty the properties above will be read ;
* if a value is provided it will be prefixed to each property
* ( exactly , so if you want to use "my.database.url" you must
* pass "my." as the prefix )
* @throws DatabaseException if the property file could not be read for any reason
* /
public static DatabaseProviderBuilder fromProperties ( Properties properties , String propertyPrefix ) {
return fromProperties ( properties , propertyPrefix , false ) ;
}
/ * *
* Configure the database from up to five properties read from the specified
* properties file , or from the system properties ( system properties will take
* precedence over the file ) :
* < pre >
* database . url = . . . Database connect string ( required )
* database . user = . . . Authenticate as this user ( optional if provided in url )
* database . password = . . . User password ( optional if user and password provided in
* url ; prompted on standard input if user is provided and
* password is not )
* database . flavor = . . . What kind of database it is ( optional , will guess based
* on the url if this is not provided )
* database . driver = . . . The Java class of the JDBC driver to load ( optional , will
* guess based on the flavor if this is not provided )
* < / pre >
* < p > This will use the JVM default character encoding to read the property file . < / p >
*
* @param filename path to the properties file we will attempt to read ; if the file
* cannot be read for any reason ( e . g . does not exist ) a debug level
* log entry will be entered , but it will attempt to proceed using
* solely the system properties
* /
public static DatabaseProviderBuilder fromPropertyFileOrSystemProperties ( String filename ) {
return fromPropertyFileOrSystemProperties ( filename , Charset . defaultCharset ( ) . newDecoder ( ) ) ;
}
/ * *
* Configure the database from up to five properties read from the specified
* properties file , or from the system properties ( system properties will take
* precedence over the file ) :
* < pre >
* database . url = . . . Database connect string ( required )
* database . user = . . . Authenticate as this user ( optional if provided in url )
* database . password = . . . User password ( optional if user and password provided in
* url ; prompted on standard input if user is provided and
* password is not )
* database . flavor = . . . What kind of database it is ( optional , will guess based
* on the url if this is not provided )
* database . driver = . . . The Java class of the JDBC driver to load ( optional , will
* guess based on the flavor if this is not provided )
* < / pre >
*
* @param filename path to the properties file we will attempt to read ; if the file
* cannot be read for any reason ( e . g . does not exist ) a debug level
* log entry will be entered , but it will attempt to proceed using
* solely the system properties
* @param decoder character encoding to use when reading the property file
* /
public static DatabaseProviderBuilder fromPropertyFileOrSystemProperties ( String filename , CharsetDecoder decoder ) {
Properties properties = new Properties ( ) ;
if ( filename ! = null & & filename . length ( ) > 0 ) {
try (
FileInputStream fis = new FileInputStream ( filename ) ;
InputStreamReader reader = new InputStreamReader ( fis , decoder )
) {
properties . load ( reader ) ;
} catch ( Exception e ) {
log . fine ( "Trying system properties - unable to read properties file: " + filename ) ;
}
}
return fromProperties ( properties , "" , true ) ;
}
/ * *
* Configure the database from up to five properties read from the specified
* properties file , or from the system properties ( system properties will take
* precedence over the file ) :
* < pre >
* database . url = . . . Database connect string ( required )
* database . user = . . . Authenticate as this user ( optional if provided in url )
* database . password = . . . User password ( optional if user and password provided in
* url ; prompted on standard input if user is provided and
* password is not )
* database . flavor = . . . What kind of database it is ( optional , will guess based
* on the url if this is not provided )
* database . driver = . . . The Java class of the JDBC driver to load ( optional , will
* guess based on the flavor if this is not provided )
* < / pre >
* < p > This will use the JVM default character encoding to read the property file . < / p >
*
* @param filename path to the properties file we will attempt to read ; if the file
* cannot be read for any reason ( e . g . does not exist ) a debug level
* log entry will be entered , but it will attempt to proceed using
* solely the system properties
* @param propertyPrefix if this is null or empty the properties above will be read ;
* if a value is provided it will be prefixed to each property
* ( exactly , so if you want to use "my.database.url" you must
* pass "my." as the prefix )
* /
public static DatabaseProviderBuilder fromPropertyFileOrSystemProperties ( String filename , String propertyPrefix ) {
return fromPropertyFileOrSystemProperties ( filename , propertyPrefix , Charset . defaultCharset ( ) . newDecoder ( ) ) ;
}
/ * *
* Configure the database from up to five properties read from the specified
* properties file , or from the system properties ( system properties will take
* precedence over the file ) :
* < pre >
* database . url = . . . Database connect string ( required )
* database . user = . . . Authenticate as this user ( optional if provided in url )
* database . password = . . . User password ( optional if user and password provided in
* url ; prompted on standard input if user is provided and
* password is not )
* database . flavor = . . . What kind of database it is ( optional , will guess based
* on the url if this is not provided )
* database . driver = . . . The Java class of the JDBC driver to load ( optional , will
* guess based on the flavor if this is not provided )
* < / pre >
*
* @param filename path to the properties file we will attempt to read ; if the file
* cannot be read for any reason ( e . g . does not exist ) a debug level
* log entry will be entered , but it will attempt to proceed using
* solely the system properties
* @param propertyPrefix if this is null or empty the properties above will be read ;
* if a value is provided it will be prefixed to each property
* ( exactly , so if you want to use "my.database.url" you must
* pass "my." as the prefix )
* @param decoder character encoding to use when reading the property file
* /
public static DatabaseProviderBuilder fromPropertyFileOrSystemProperties ( String filename , String propertyPrefix ,
CharsetDecoder decoder ) {
Properties properties = new Properties ( ) ;
if ( filename ! = null & & filename . length ( ) > 0 ) {
try (
FileInputStream fis = new FileInputStream ( filename ) ;
InputStreamReader reader = new InputStreamReader ( fis , decoder )
) {
properties . load ( reader ) ;
} catch ( Exception e ) {
log . fine ( "Trying system properties - unable to read properties file: " + filename ) ;
}
}
return fromProperties ( properties , propertyPrefix , true ) ;
}
/ * *
* Configure the database from up to five system properties :
* < pre >
* - Ddatabase . url = . . . Database connect string ( required )
* - Ddatabase . user = . . . Authenticate as this user ( optional if provided in url )
* - Ddatabase . password = . . . User password ( optional if user and password provided in
* url ; prompted on standard input if user is provided and
* password is not )
* - Ddatabase . flavor = . . . What kind of database it is ( optional , will guess based
* on the url if this is not provided )
* - Ddatabase . driver = . . . The Java class of the JDBC driver to load ( optional , will
* guess based on the flavor if this is not provided )
* < / pre >
* /
public static DatabaseProviderBuilder fromSystemProperties ( ) {
return fromProperties ( null , "" , true ) ;
}
/ * *
* Configure the database from up to five system properties :
* < pre >
* - D { prefix } database . url = . . . Database connect string ( required )
* - D { prefix } database . user = . . . Authenticate as this user ( optional if provided in url )
* - D { prefix } database . password = . . . User password ( optional if user and password provided in
* url ; prompted on standard input if user is provided and
* password is not )
* - D { prefix } database . flavor = . . . What kind of database it is ( optional , will guess based
* on the url if this is not provided )
* - D { prefix } database . driver = . . . The Java class of the JDBC driver to load ( optional , will
* guess based on the flavor if this is not provided )
* < / pre >
*
* @param propertyPrefix a prefix to attach to each system property - be sure to include the
* dot if desired ( e . g . "mydb." for properties like - Dmydb . database . url )
* /
public static DatabaseProviderBuilder fromSystemProperties ( String propertyPrefix ) {
return fromProperties ( null , propertyPrefix , true ) ;
}
private static DatabaseProviderBuilder fromProperties ( Properties properties , String propertyPrefix , boolean useSystemProperties ) {
if ( propertyPrefix = = null ) {
propertyPrefix = "" ;
}
String driver ;
String flavorStr ;
String url ;
String user ;
String password ;
if ( useSystemProperties ) {
if ( properties = = null ) {
properties = new Properties ( ) ;
}
driver = System . getProperty ( propertyPrefix + "database.driver" ,
properties . getProperty ( propertyPrefix + "database.driver" ) ) ;
flavorStr = System . getProperty ( propertyPrefix + "database.flavor" ,
properties . getProperty ( propertyPrefix + "database.flavor" ) ) ;
url = System . getProperty ( propertyPrefix + "database.url" ,
properties . getProperty ( propertyPrefix + "database.url" ) ) ;
user = System . getProperty ( propertyPrefix + "database.user" ,
properties . getProperty ( propertyPrefix + "database.user" ) ) ;
password = System . getProperty ( propertyPrefix + "database.password" ,
properties . getProperty ( propertyPrefix + "database.password" ) ) ;
} else {
if ( properties = = null ) {
throw new DatabaseException ( "No properties were provided" ) ;
}
driver = properties . getProperty ( propertyPrefix + "database.driver" ) ;
flavorStr = properties . getProperty ( propertyPrefix + "database.flavor" ) ;
url = properties . getProperty ( propertyPrefix + "database.url" ) ;
user = properties . getProperty ( propertyPrefix + "database.user" ) ;
password = properties . getProperty ( propertyPrefix + "database.password" ) ;
}
if ( url = = null ) {
throw new DatabaseException ( "You must use -D" + propertyPrefix + "database.url=..." ) ;
}
if ( user ! = null & & password = = null ) {
System . out . println ( "Enter database password for user " + user + ":" ) ;
byte [ ] input = new byte [ 256 ] ;
try {
int bytesRead = System . in . read ( input ) ;
password = new String ( input , 0 , bytesRead - 1 , Charset . defaultCharset ( ) ) ;
} catch ( IOException e ) {
throw new DatabaseException ( "Error reading password from standard input" , e ) ;
}
}
Flavor flavor ;
if ( flavorStr ! = null ) {
flavor = Flavor . valueOf ( flavorStr ) ;
} else {
flavor = Flavor . fromJdbcUrl ( url ) ;
}
if ( driver ! = null ) {
try {
Class . forName ( driver ) . getDeclaredConstructor ( ) . newInstance ( ) ;
} catch ( Exception e ) {
driver = flavor . driverClass ( ) ;
try {
Class . forName ( driver ) . getDeclaredConstructor ( ) . newInstance ( ) ;
} catch ( Exception ee ) {
throw new DatabaseException ( "Unable to load JDBC driver: " + driver , ee ) ;
}
}
}
if ( user = = null ) {
return builder ( url , flavor ) ;
} else {
return builder ( url , flavor , user , password ) ;
}
}
private static DataSource createDataSource ( Config config )
throws ClassNotFoundException , InvocationTargetException , NoSuchMethodException , InstantiationException ,
IllegalAccessException {
@ -749,7 +280,7 @@ public final class DatabaseProvider implements Supplier<Database>, Closeable {
if ( builder . isClosed ( ) ) {
throw new DatabaseException ( "Called get() on a DatabaseProvider after close()" ) ;
}
Metric metric = new Metric ( log . isLoggable ( Level . FINE ) ) ;
Metric metric = new Metric ( log ger . isLoggable ( Level . FINE ) ) ;
try {
connection = builder . connectionProvider . get ( ) ;
metric . checkpoint ( "getConn" ) ;
@ -770,10 +301,10 @@ public final class DatabaseProvider implements Supplier<Database>, Closeable {
throw e ;
} finally {
metric . done ( ) ;
if ( log . isLoggable ( Level . FINE ) ) {
if ( log ger . isLoggable ( Level . FINE ) ) {
StringBuilder buf = new StringBuilder ( "Get " ) . append ( builder . options . flavor ( ) ) . append ( " database: " ) ;
metric . printMessage ( buf ) ;
log . fine ( buf . toString ( ) ) ;
log ger . fine ( buf . toString ( ) ) ;
}
}
return database ;
@ -811,7 +342,7 @@ public final class DatabaseProvider implements Supplier<Database>, Closeable {
connection . rollback ( ) ;
}
} catch ( Exception e ) {
log . log ( Level . SEVERE , "Unable to rollback the transaction" , e ) ;
log ger . log ( Level . SEVERE , "Unable to rollback the transaction" , e ) ;
}
}
}
@ -825,7 +356,7 @@ public final class DatabaseProvider implements Supplier<Database>, Closeable {
}
close ( ) ;
} catch ( Exception e ) {
log . log ( Level . SEVERE , "Unable to rollback the transaction" , e ) ;
log ger . log ( Level . SEVERE , "Unable to rollback the transaction" , e ) ;
}
}
@ -835,7 +366,7 @@ public final class DatabaseProvider implements Supplier<Database>, Closeable {
try {
connection . close ( ) ;
} catch ( Exception e ) {
log . log ( Level . SEVERE , "Unable to close the database connection" , e ) ;
log ger . log ( Level . SEVERE , "Unable to close the database connection" , e ) ;
}
}
connection = null ;
@ -843,129 +374,6 @@ public final class DatabaseProvider implements Supplier<Database>, Closeable {
builder . close ( ) ;
}
/ * *
* This builder is immutable , so setting various options does not affect
* the previous instance . This is intended to make it safe to pass builders
* around without risk someone will reconfigure it .
* /
public interface DatabaseProviderBuilder {
DatabaseProviderBuilder withOptions ( OptionsOverride options ) ;
/ * *
* Enable logging of parameter values along with the SQL .
* /
DatabaseProviderBuilder withSqlParameterLogging ( ) ;
/ * *
* Include SQL in exception messages . This will also include parameters in the
* exception messages if SQL parameter logging is enabled . This is handy for
* development , but be careful as this is an information disclosure risk ,
* dependent on how the exception are caught and handled .
* /
DatabaseProviderBuilder withSqlInExceptionMessages ( ) ;
/ * *
* Wherever argDateNowPerDb ( ) is specified , use argDateNowPerApp ( ) instead . This is
* useful for testing purposes as you can use OptionsOverride to provide your
* own system clock that will be used for time travel .
* /
DatabaseProviderBuilder withDatePerAppOnly ( ) ;
/ * *
* Allow provided Database instances to explicitly control transactions using the
* commitNow ( ) and rollbackNow ( ) methods . Otherwise calling those methods would
* throw an exception .
* /
DatabaseProviderBuilder withTransactionControl ( ) ;
/ * *
* This can be useful when testing code , as it can pretend to use transactions ,
* while giving you control over whether it actually commits or rolls back .
* /
DatabaseProviderBuilder withTransactionControlSilentlyIgnored ( ) ;
/ * *
* Allow direct access to the underlying database connection . Normally this is
* not allowed , and is a bad idea , but it can be helpful when migrating from
* legacy code that works with raw JDBC .
* /
DatabaseProviderBuilder withConnectionAccess ( ) ;
/ * *
* WARNING : You should try to avoid using this method . If you use it more
* that once or twice in your entire codebase you are probably doing
* something wrong .
*
* < p > If you use this method you are responsible for managing
* the transaction and commit / rollback / close . < / p >
* /
DatabaseProvider build ( ) ;
/ * *
* This is a convenience method to eliminate the need for explicitly
* managing the resources ( and error handling ) for this class . After
* the run block is complete the transaction will commit unless the
* { @link DbCode # run ( Supplier ) run ( Supplier ) } method threw a { @link Throwable } .
*
* < p > Here is a typical usage :
* < pre >
* dbp . transact ( dbs - & gt ; {
* List < String > r = dbs . get ( ) . toSelect ( "select a from b where c=?" ) . argInteger ( 1 ) . queryStrings ( ) ;
* . . . do something with the results . . .
* } ) ;
* < / pre >
* < / p >
*
* @param code the code you want to run as a transaction with a Database
* @see # transact ( DbCodeTx )
* /
void transact ( DbCode code ) ;
/ * *
* This method is the same as { @link # transact ( DbCode ) } but allows a return value .
*
* < p > Here is a typical usage :
* < pre >
* List < String > r = dbp . transact ( dbs - & gt ; {
* return dbs . get ( ) . toSelect ( "select a from b where c=?" ) . argInteger ( 1 ) . queryStrings ( ) ;
* } ) ;
* < / pre >
* < / p >
* /
< T > T transactReturning ( DbCodeTyped < T > code ) ;
/ * *
* This is a convenience method to eliminate the need for explicitly
* managing the resources ( and error handling ) for this class . After
* the run block is complete commit ( ) will be called unless either the
* { @link DbCodeTx # run ( Supplier , Transaction ) } method threw a { @link Throwable }
* while { @link Transaction # isRollbackOnError ( ) } returns true , or
* { @link Transaction # isRollbackOnly ( ) } returns a true value .
*
* < p > Here is a typical usage :
* < pre >
* dbp . transact ( ( dbs , tx ) - & gt ; {
* tx . setRollbackOnError ( false ) ;
* dbs . get ( ) . toInsert ( "..." ) . argInteger ( 1 ) . insert ( 1 ) ;
* . . . some stuff that might fail . . .
* } ) ;
* < / pre >
* < / p >
*
* @param code the code you want to run as a transaction with a Database
* /
void transact ( DbCodeTx code ) ;
}
private static class DatabaseProviderBuilderImpl implements DatabaseProviderBuilder , Closeable {
private DataSource dataSource ;