hi matej
On Tue, Jul 22, 2008 at 1:39 AM, Matej Knopp <[EMAIL PROTECTED]> wrote:
> Hi,
>
> The idea of Jackrabbit managing DataSources didn't gain much support,
> so I decided to try implementing something much less intrusive. I have
> abstracted connection creation/closing (ConnectionProvider[1]) from
> the components that use database connections. There is one instance of
> ConnectionProvider per repository, configurable in repository.xml, but
> possibly with a sane default implementation so no configuration is
> necessary.
>
> The rest of jackrabbit (components that touch the database) would use
> ConnectionProvider to get the connections instead of just creating
> them and keeping opened. So far I've converted
> BundleDbPersistenceManager (and it's subclasses) to this approach. I
> would also tweak DatabasePersistenceManager and DbFileSystem to just
> borrow the connections instead of keeping them. As for journal,
> keeping one opened connection per repository probably doesn't make
> much difference.
>
> The benefit of this approach is that there is zero change in
> repository configuration, unless user wants to specify it's own
> ConnectionProvider class, which can be specified as a simple bean with
> element name ConnectionProvider.
>
> ConnectionProvider implementation that supports pooling must take
> different things into account, such as there can be request to various
> connections from different databases with different URLs. The manager
> must be intelligent enough to possibly maintain group of pools (e..g
> per database or even per connection URL)
>
> There is a SimplePoolingConnectionProvider implementation included in
> the patch that implements connection pooling, but it's only meant as
> proof of concept and doesn't try to substitute "real" connection
> pooling alternatives (dbcp, etc.)
>
> I've attached the first patch to
> https://issues.apache.org/jira/browse/JCR-1456
thanks for the patch. i added my comments on the jira issue.
cheers
stefan
>
> Kind regards,
> -Matej
>
> [1] ConnectionProvider class
>
> /**
> * Class responsible for providing SQL [EMAIL PROTECTED] Connection}s.
> * <p>
> * Implementation of this class can do connection pooling, in which case it
> must
> * take [EMAIL PROTECTED] ConnectionProperties} into account and only return
> connection
> * that matches the specified properties.
> */
> public interface ConnectionProvider {
>
> /**
> * Returns connection with given properties.
> *
> * @param properties
> * connection properties
> * @return SQL [EMAIL PROTECTED] Connection}
> *
> * @throws RepositoryException
> * @throws SQLException
> */
> public Connection getConnection(ConnectionProperties properties)
> throws RepositoryException, SQLException;
>
> /**
> * Closes the given connection. Classes that obtain connections through
> * [EMAIL PROTECTED] ConnectionProvider} must never call [EMAIL PROTECTED]
> Connection#close()}
> * directly. They are required to call [EMAIL PROTECTED]
> #closeConnection(Connection)}
> * instead.
> *
> * @param connection
> * SQL [EMAIL PROTECTED] Connection}
> *
> * @throws SQLException
> */
> public void closeConnection(Connection connection) throws SQLException;
>
> /**
> * Invoked when the repository is being shut down.
> *
> * @throws RepositoryException
> */
> public void dispose() throws RepositoryException;
>
> /**
> * Bean that holds properties necessary to create or identify a SQL
> * [EMAIL PROTECTED] Connection}.
> */
> public final static class ConnectionProperties {
> private String user;
> private String password;
> private String url;
> private String driver;
>
> public String getUser() {
> return user;
> }
>
> public void setUser(String user) {
> this.user = user;
> }
>
> public String getPassword() {
> return password;
> }
>
> public void setPassword(String password) {
> this.password = password;
> }
>
> public String getUrl() {
> return url;
> }
>
> public void setUrl(String url) {
> this.url = url;
> }
>
> public void setDriver(String driver) {
> this.driver = driver;
> }
>
> public String getDriver() {
> return driver;
> }
>
> private boolean equals(String s1, String s2) {
> return s1 == s2 || (s1 != null && s1.equals(s2));
> }
>
> public boolean equals(Object obj) {
> if (this == obj) {
> return true;
> }
> if (obj instanceof ConnectionProperties == false) {
> return false;
> }
> ConnectionProperties cp = (ConnectionProperties) obj;
> return equals(user, cp.user) && equals(password, cp.password)
> && equals(url, cp.url) && equals(driver, cp.driver);
>
> }
>
> private int hashCode(String s) {
> return s != null ? s.hashCode() : 0;
> }
>
> public int hashCode() {
> return hashCode(user) + 37 * hashCode(password) + 373
> & hashCode(url) + 1187 * hashCode(driver);
> }
> }
> }
>