You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by Darrell DeBoer <li...@bigdaz.com> on 2001/06/10 09:06:47 UTC

[PATCH] JDBC-backed UsersRepository implementation.

G'day,

This is my first ever patch submission, so forgive me if don't get it quite 
right. 

I've managed to get a database-backed UsersRepository implementation up and 
running, which is included here. A few things to note:

1) The code currently connects directly to a database, but it shouldn't be 
too hard to get it to use the JdbcDataSource in 
org.apache.avalon.excalibur.datasource. (I haven't quite worked out how to 
set up components yet, so I haven't done this myself).  I have, however, made 
the database configuration mirror that of the JdbcDataSource component, so 
that we should be able to pass it straight through.

2) Basically, I've got vanilla SQL working with MySQL, M$SQL Server and 
Oracle8i, although I'm getting some wierd problems with M$SQL using the 
JDBC-ODBC bridge (Inet Sprinta driver (Type IV) works fine). Presently, the 
SQL strings are hard-coded, but they could easily be set up during 
configuration, if necessary.

3) One usability feature I've added is that the component checks for a table 
named "JamesUsers" at start-up. If it's not present, the table is created. 
This eliminates the need to run a database script as a separate part of 
installation.

4) I've built some JUnit tests so that I can check on all combinations 
quickly and easily - these are included. I've also added a target to the 
build file to run these, but it requires adding JUnit to the "tools/lib" 
directory. Is there a plan/framework in place for testing? I saw a mention of 
"testlets" under Avalon - but I haven't investigated further... 

One thing that would be nice is a framework for testing components. At the 
moment I can't test the UsersFileRepository with the UsersRepositoryTest I've 
written, because I'm not sure how to get an initialised ComponentManager 
instance for initialisation. Does something like this exist?

5) The UsersRepository interface takes objects of type "User", making it hard 
to access the underlying extended properties of the "JamesUser" interface 
(aliasing, forwarding). I guess this works fine for a serialisation-based 
repository, but not so well for writing to a database. I've got around this 
by type-checking and casting at run-time, but ideally the UsersRepository 
interface would access "JamesUser" objects for insertion/update. (Is there 
any reason to have separate User & JamesUser interfaces? (or 
implementations?). I'd probably look at flattening them, if not.

ciao
Daz

Attached file patch.tar.gz
---- patches ------
patch.diff 	Diff against current cvs - build.xml
					proposals/v1.3/java/org/apache/james/userrepository/DefaultUser.java
					proposals/v1.3/conf/james-config.java
---- new files ------
proposal/v1.3/java/org/apache/james/userrepository/AbstractUsersRepository.java	
proposal/v1.3/java/org/apache/james/userrepository/UsersJDBCRepository.java
proposal/v1.3/java/org/apache/james/testing/TestUsersRepository.java
proposal/v1.3/java/org/apache/james/testing/TestUsersJDBCRepository.java	

Re: [PATCH] JDBC-backed UsersRepository implementation.

Posted by Charles Benett <ch...@benett1.demon.co.uk>.
Committed, thanks!
Charles
PS My version seemed to have spaces not tabs anyway. Bizarre.
C

Darrell DeBoer wrote:
> 
> Hi,
> 
> The minor fix I sent for MySQL seems to have got corrupted. The real one is
> included here. Note that a few changes are just replacing tabs with spaces.
> 
> ciao
> Daz
> 
> Index:
> proposals/v1.3/java/org/apache/james/userrepository/UsersJDBCRepository.java
> ===================================================================
> RCS file:
> /home/cvspublic/jakarta-james/proposals/v1.3/java/org/apache/james/userrepository/UsersJDBCRepository.java,v
> retrieving revision 1.1
> diff -r1.1 UsersJDBCRepository.java
> 87c87
> <       getLogger().debug("Loading driver :" + driverName);
> ---
> >         getLogger().debug("Loading driver :" + driverName);
> 90c90
> <           getLogger().info("Database driver " + driverName + " loaded");
> ---
> >             getLogger().info("Database driver " + driverName + " loaded");
> 140c140
> <               getLogger().info("Created \'JamesUsers\' table.");
> ---
> >                 getLogger().info("Created \'JamesUsers\' table.");
> 212c212
> <         boolean useForwarding = user.getForwarding();
> ---
> >         int useForwarding = user.getForwarding() ? 1 : 0 ;
> 218c218
> <         boolean useAlias = user.getAliasing();
> ---
> >         int useAlias = user.getAliasing() ? 1 : 0 ;
> 230c230
> <             addUserStatement.setBoolean(4, useForwarding);
> ---
> >             addUserStatement.setInt(4, useForwarding);
> 232c232
> <             addUserStatement.setBoolean(6, useAlias);
> ---
> >             addUserStatement.setInt(6, useAlias);
> 345c345
> <         boolean useForwarding = user.getForwarding();
> ---
> >         int useForwarding = user.getForwarding() ? 1 : 0 ;
> 351c351
> <         boolean useAlias = user.getAliasing();
> ---
> >         int useAlias = user.getAliasing() ? 1 : 0 ;
> 362c362
> <             updateUserStatement.setBoolean(3, useForwarding);
> ---
> >             updateUserStatement.setInt(3, useForwarding);
> 364c364
> <             updateUserStatement.setBoolean(5, useAlias);
> ---
> >             updateUserStatement.setInt(5, useAlias);
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: james-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: james-dev-help@jakarta.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: james-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: james-dev-help@jakarta.apache.org


Re: [PATCH] JDBC-backed UsersRepository implementation.

Posted by Darrell DeBoer <li...@bigdaz.com>.
Hi,

The minor fix I sent for MySQL seems to have got corrupted. The real one is 
included here. Note that a few changes are just replacing tabs with spaces.

ciao
Daz

Index: 
proposals/v1.3/java/org/apache/james/userrepository/UsersJDBCRepository.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-james/proposals/v1.3/java/org/apache/james/userrepository/UsersJDBCRepository.java,v
retrieving revision 1.1
diff -r1.1 UsersJDBCRepository.java
87c87
< 	getLogger().debug("Loading driver :" + driverName);
---
>         getLogger().debug("Loading driver :" + driverName);
90c90
< 	    getLogger().info("Database driver " + driverName + " loaded");
---
>             getLogger().info("Database driver " + driverName + " loaded");
140c140
< 		getLogger().info("Created \'JamesUsers\' table.");
---
>                 getLogger().info("Created \'JamesUsers\' table.");
212c212
<         boolean useForwarding = user.getForwarding();
---
>         int useForwarding = user.getForwarding() ? 1 : 0 ;
218c218
<         boolean useAlias = user.getAliasing();
---
>         int useAlias = user.getAliasing() ? 1 : 0 ;
230c230
<             addUserStatement.setBoolean(4, useForwarding);
---
>             addUserStatement.setInt(4, useForwarding);
232c232
<             addUserStatement.setBoolean(6, useAlias);
---
>             addUserStatement.setInt(6, useAlias);
345c345
<         boolean useForwarding = user.getForwarding();
---
>         int useForwarding = user.getForwarding() ? 1 : 0 ;
351c351
<         boolean useAlias = user.getAliasing();
---
>         int useAlias = user.getAliasing() ? 1 : 0 ;
362c362
<             updateUserStatement.setBoolean(3, useForwarding);
---
>             updateUserStatement.setInt(3, useForwarding);
364c364
<             updateUserStatement.setBoolean(5, useAlias);
---
>             updateUserStatement.setInt(5, useAlias);

---------------------------------------------------------------------
To unsubscribe, e-mail: james-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: james-dev-help@jakarta.apache.org


Re: [PATCH] JDBC-backed UsersRepository implementation.

Posted by Darrell DeBoer <li...@bigdaz.com>.
Hi Charles.

> > Two reasons for failure:
> > 1) I built this on the latest JUnit (v3.7) .
...
>
> If you send me the latest jar directly, I'll add it to cvs.

Try this:
http://download.sourceforge.net/junit/junit3.7.zip 
(or www.junit.org).

However, maybe wait off commiting those tests until I've had a look at this 
component intialisation stuff. They aren't much use to anyone else as they 
are.

Currently, the database names, IP addresses etc are hard-coded, which makes 
it a bit painful to run the tests. Once I get initialisation sorted, I'll set 
up the tests to load dbConfig from a test definition file, so it'll be easier 
for others to configure the tests to run. This will also allow one to run the 
tests against other UserRepository implementations, as well as to write tests 
for other key components (eg MailRepository).

ciao
Daz

---------------------------------------------------------------------
To unsubscribe, e-mail: james-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: james-dev-help@jakarta.apache.org


Re: [PATCH] JDBC-backed UsersRepository implementation.

Posted by Charles Benett <ch...@benett1.demon.co.uk>.
Darrell DeBoer wrote:
> 
> Hi,
> 
> > I've got your UsersJDBCRepository up and working with mysql. Cool!
> > I've committed AbstractUsersRepository, UsersJDBCRepository and
> > mysql.jar.
> 
> So quickly...!
Just lucky!

> 
> >
> > However ... aliasing and forwarding doesn't seem to work. :-(
> >
> 
> Hmmm... this was something I hadn't added to the tests yet, since it wasn't
> being used. When I added tests for this, 3 of the 4 database configurations
> passed (including MySQL with JDBC/ODBC) but MySQL with MM Jdbc driver failed.
> It seems like the Jdbc driver won't accept a PreparedStatement.setBoolean()
> call on a SMALLINT column (I use SMALLINT as a widely available boolean
> column type in SQL).
> 
> I've patched UsersJDBCRepository to use PreparedStatement.setInt() instead,
> and it seems to work OK. (Patch included). I'll submit the patch for the
> updated tests when/if they are added to cvs.
> 
> > I've added junit-3.2.jar (copied from jakarta-turbine) but I get a bunch
> > of compile errors. Hence haven't committed testing classes yet. What
> > exact version are you using?
> 
> Two reasons for failure:
> 1) I built this on the latest JUnit (v3.7) and somewhere along the line the
> method "assert(boolean)" was deprecated and replaced with
> "assertTrue(boolean)". We can either use the latest JUnit version, or replace
> "assertTrue" with "assert" in the source.

If you send me the latest jar directly, I'll add it to cvs.

> 
> 2) You need to add JUnit to the tools/lib directory, so ant can run the
> <junit> task. I guess ant then adds JUnit to the classpath for the <javac>
> target.

Don't know. I'll try it when you send the jar.

> 
> >(stdout-based) DefaultLogger.java
> > WRT testlets, long-term they may be better but short term we can use
> > anything.
> > No idea on ComponentManager q, off hand.
> 
> Unfortunately, having getLogger() calls in UsersJDBCRepository causes the
> tests to return a null pointer exception, since the component isn't properly
> composed/configured. Where should I look to work out how to properly
> initialise a Component for testing? eg I'd like to have a simple Logger
> implementation to use for testing.

Hmm. But you also had problems with testing UsersFileRepository. 
I guess we need to find a way of testing Avalon-Phoenix stuff with
composed etc. components.
Probably have to dig through avalon-dev archive and ask on that list.

Charles

---------------------------------------------------------------------
To unsubscribe, e-mail: james-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: james-dev-help@jakarta.apache.org


Re: [PATCH] JDBC-backed UsersRepository implementation.

Posted by Darrell DeBoer <da...@mathiasco.co.uk>.
Hi,

> I've got your UsersJDBCRepository up and working with mysql. Cool!
> I've committed AbstractUsersRepository, UsersJDBCRepository and
> mysql.jar.

So quickly...!

>
> However ... aliasing and forwarding doesn't seem to work. :-(
>

Hmmm... this was something I hadn't added to the tests yet, since it wasn't 
being used. When I added tests for this, 3 of the 4 database configurations 
passed (including MySQL with JDBC/ODBC) but MySQL with MM Jdbc driver failed. 
It seems like the Jdbc driver won't accept a PreparedStatement.setBoolean() 
call on a SMALLINT column (I use SMALLINT as a widely available boolean 
column type in SQL).

I've patched UsersJDBCRepository to use PreparedStatement.setInt() instead, 
and it seems to work OK. (Patch included). I'll submit the patch for the 
updated tests when/if they are added to cvs.

> I've added junit-3.2.jar (copied from jakarta-turbine) but I get a bunch
> of compile errors. Hence haven't committed testing classes yet. What
> exact version are you using?

Two reasons for failure:
1) I built this on the latest JUnit (v3.7) and somewhere along the line the 
method "assert(boolean)" was deprecated and replaced with 
"assertTrue(boolean)". We can either use the latest JUnit version, or replace 
"assertTrue" with "assert" in the source.

2) You need to add JUnit to the tools/lib directory, so ant can run the 
<junit> task. I guess ant then adds JUnit to the classpath for the <javac> 
target.

>(stdout-based) DefaultLogger.java
> WRT testlets, long-term they may be better but short term we can use
> anything.
> No idea on ComponentManager q, off hand.

Unfortunately, having getLogger() calls in UsersJDBCRepository causes the 
tests to return a null pointer exception, since the component isn't properly 
composed/configured. Where should I look to work out how to properly 
initialise a Component for testing? eg I'd like to have a simple Logger 
implementation to use for testing.

ciao
Daz

Index: 
proposals/v1.3/java/org/apache/james/userrepository/UsersJDBCRepository.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-james/proposals/v1.3/java/org/apache/james/userrepository/UsersJDBCRepository.java,v
retrieving revision 1.1
diff -r1.1 UsersJDBCRepository.java
87c87
< 	getLogger().debug("Loading driver :" + driverName);
---
>         getLogger().debug("Loading driver :" + driverName);
90c90
< 	    getLogger().info("Database driver " + driverName + " loaded");
---
> 	        getLogger().info("Database driver " + driverName + " loaded");
140c140
< 		getLogger().info("Created \'JamesUsers\' table.");
---
>                 getLogger().info("Created \'JamesUsers\' table.");
212c212
<         boolean useForwarding = user.getForwarding();
---
>         int useForwarding = user.getForwarding() ? 1 : 0 ; // boolean 
causes problems.
218c218
<         boolean useAlias = user.getAliasing();
---
>         int useAlias = user.getAliasing() ? 1 : 0 ;
230c230
<             addUserStatement.setBoolean(4, useForwarding);
---
>             addUserStatement.setInt(4, useForwarding);
232c232
<             addUserStatement.setBoolean(6, useAlias);
---
>             addUserStatement.setInt((stdout-based) 
DefaultLogger.java(stdout-based) DefaultLogger.java6, useAlias);
345c345
<         boolean useForwarding = user.getForwarding();
---
>         int useForwarding = user.getForwarding() ? 1 : 0 ; // boolean 
causes problems.
351c351
<         boolean useAlias = user.getAliasing();
---
>         int useAlias = user.getAliasing() ? 1 : 0 ;
362c362
<             updateUserStatement.setBoolean(3, useForwarding);
---
>             updateUserStatement.setInt(3, useForwarding);
364c364
<             updateUserStatement.setBoolean(5, useAlias);
---
>             updateUserStatement.setInt(5, useAlias);



---------------------------------------------------------------------
To unsubscribe, e-mail: james-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: james-dev-help@jakarta.apache.org


Re: [PATCH] JDBC-backed UsersRepository implementation.

Posted by Charles Benett <ch...@benett1.demon.co.uk>.
Charles Benett wrote:
> 
> Darrell DeBoer wrote:
> >
> > G'day,
> >
> > This is my first ever patch submission, so forgive me if don't get it quite
> > right.
> 
> Congratulations, Daz! Tarball is cool. Minor niggle, can you use cvs
> diff -u in future?

Oh! And 80 columns please! There's a coding standards doc somewhere...

> 
> >
> > I've managed to get a database-backed UsersRepository implementation up and
> > running, which is included here. A few things to note:
> >
> > 1) The code currently connects directly to a database, but it shouldn't be
> > too hard to get it to use the JdbcDataSource in
> > org.apache.avalon.excalibur.datasource. (I haven't quite worked out how to
> > set up components yet, so I haven't done this myself).  I have, however, made
> > the database configuration mirror that of the JdbcDataSource component, so
> > that we should be able to pass it straight through.
> >
> > 2) Basically, I've got vanilla SQL working with MySQL, M$SQL Server and
> > Oracle8i, although I'm getting some wierd problems with M$SQL using the
> > JDBC-ODBC bridge (Inet Sprinta driver (Type IV) works fine). Presently, the
> > SQL strings are hard-coded, but they could easily be set up during
> > configuration, if necessary.
> >
> > 3) One usability feature I've added is that the component checks for a table
> > named "JamesUsers" at start-up. If it's not present, the table is created.
> > This eliminates the need to run a database script as a separate part of
> > installation.
> 
> I've got your UsersJDBCRepository up and working with mysql. Cool!
> I've committed AbstractUsersRepository, UsersJDBCRepository and
> mysql.jar.
> 
> However ... aliasing and forwarding doesn't seem to work. :-(

Specifcially, the alias and forwarding dest appear in the db table, but
useAlias and useForwarding cols remain with 0.

Charles

---------------------------------------------------------------------
To unsubscribe, e-mail: james-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: james-dev-help@jakarta.apache.org


Re: [PATCH] JDBC-backed UsersRepository implementation.

Posted by Charles Benett <ch...@benett1.demon.co.uk>.
Darrell DeBoer wrote:
> 
> G'day,
> 
> This is my first ever patch submission, so forgive me if don't get it quite
> right.

Congratulations, Daz! Tarball is cool. Minor niggle, can you use cvs
diff -u in future?

> 
> I've managed to get a database-backed UsersRepository implementation up and
> running, which is included here. A few things to note:
> 
> 1) The code currently connects directly to a database, but it shouldn't be
> too hard to get it to use the JdbcDataSource in
> org.apache.avalon.excalibur.datasource. (I haven't quite worked out how to
> set up components yet, so I haven't done this myself).  I have, however, made
> the database configuration mirror that of the JdbcDataSource component, so
> that we should be able to pass it straight through.
> 
> 2) Basically, I've got vanilla SQL working with MySQL, M$SQL Server and
> Oracle8i, although I'm getting some wierd problems with M$SQL using the
> JDBC-ODBC bridge (Inet Sprinta driver (Type IV) works fine). Presently, the
> SQL strings are hard-coded, but they could easily be set up during
> configuration, if necessary.
> 
> 3) One usability feature I've added is that the component checks for a table
> named "JamesUsers" at start-up. If it's not present, the table is created.
> This eliminates the need to run a database script as a separate part of
> installation.

I've got your UsersJDBCRepository up and working with mysql. Cool!
I've committed AbstractUsersRepository, UsersJDBCRepository and
mysql.jar.

However ... aliasing and forwarding doesn't seem to work. :-(

> 
> 4) I've built some JUnit tests so that I can check on all combinations
> quickly and easily - these are included. I've also added a target to the
> build file to run these, but it requires adding JUnit to the "tools/lib"
> directory. Is there a plan/framework in place for testing? I saw a mention of
> "testlets" under Avalon - but I haven't investigated further...
> 
> One thing that would be nice is a framework for testing components. At the
> moment I can't test the UsersFileRepository with the UsersRepositoryTest I've
> written, because I'm not sure how to get an initialised ComponentManager
> instance for initialisation. Does something like this exist?

I've added junit-3.2.jar (copied from jakarta-turbine) but I get a bunch
of compile errors. Hence haven't committed testing classes yet. What
exact version are you using?

WRT testlets, long-term they may be better but short term we can use
anything.
No idea on ComponentManager q, off hand.

> 
> 5) The UsersRepository interface takes objects of type "User", making it hard
> to access the underlying extended properties of the "JamesUser" interface
> (aliasing, forwarding). I guess this works fine for a serialisation-based
> repository, but not so well for writing to a database. I've got around this
> by type-checking and casting at run-time, but ideally the UsersRepository
> interface would access "JamesUser" objects for insertion/update. (Is there
> any reason to have separate User & JamesUser interfaces? (or
> implementations?). I'd probably look at flattening them, if not.

My original idea was to separate the basic User, which could be used in
multiple applications, so that the User/ UserStore/ UserRepository code
could be placed in Avalon (as a Cornerstone block). Then any avalon app
could use it with app-specific extensions (eg JamesUser). Which requires
writing the repository code so that it works without knowledge of
runtime type. Ideally, we would use either reflection or db metadata to
achieve that in UsersJDBCRepository (and UserLDAPRepsoitory). Open to
suggestions though.

Charles

---------------------------------------------------------------------
To unsubscribe, e-mail: james-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: james-dev-help@jakarta.apache.org