Serge,

Please find the final patch code for Oracle. You'll need to download two 
vital classes from Oracle to support its JDBC driver (classes12.zip & 
nls_charset12.zip for national char set support).

There are 2 classes in James which needs updating and there 
JamesJDBCMailRepository and MimeMessageJDBCSource classes. Please scan for 
start/end markers for oracle implemented code and note any code removal 
which I've commented out, again these are held within the start/end block.

I have used Oracle's BLOB type which stores unstructured binary large 
objects. BLOBs can be thought of as bitstreams with no character set 
semantics. BLOBs can store up to 4 gigabytes of binary data.

So, to begin with, the code for JamesJDBCMailRepository:


/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.james.mailrepository;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import javax.mail.internet.MimeMessage;
import org.apache.avalon.cornerstone.services.store.Store;
import org.apache.avalon.cornerstone.services.store.StreamRepository;
import org.apache.avalon.cornerstone.services.datasource.DataSourceSelector;
import org.apache.avalon.excalibur.datasource.DataSourceComponent;
import org.apache.avalon.framework.CascadingRuntimeException;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.component.Composable;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.logger.AbstractLoggable;
import org.apache.avalon.phoenix.BlockContext;
import org.apache.james.core.MimeMessageWrapper;
import org.apache.james.core.MailImpl;
import org.apache.james.services.MailRepository;
import org.apache.james.services.SpoolRepository;
import org.apache.james.util.Lock;
import org.apache.james.util.SqlResources;
import org.apache.mailet.Mail;
import org.apache.mailet.MailAddress;
// Sam. Oracle code implementation of BLOB binary type.
// Need to import oracle sql packages.
// START
//needed for new CLOB and BLOB classes
import oracle.sql.*;
import oracle.jdbc.driver.*;
// END

/**
* Implementation of a MailRepository on a database.
*
* <p>Requires a configuration element in the .conf.xml file of the form:
*  <br><repository 
destinationURL="db://<datasource>/<table_name>/<repository_name>"
*  <br>            type="MAIL"
*  <br>            model="SYNCHRONOUS"/>
*  <br></repository>
* <p>destinationURL specifies..(Serge??)
* <br>Type can be SPOOL or MAIL
* <br>Model is currently not used and may be dropped
*
* <p>Requires a logger called MailRepository.
*
* @author Serge Knystautas <[EMAIL PROTECTED]>
* @author Darrell DeBoer <[EMAIL PROTECTED]>
* @version 1.0.0, 24/04/1999
*/
public class JDBCMailRepository
    extends AbstractLoggable
    implements MailRepository, Component, Contextualizable, Composable, 
Configurable, Initializable {
    protected Context context;

    private Lock lock;

    // Configuration elements
    protected String destination;
    protected String tableName;
    protected String repositoryName;
    protected String filestore;
    protected String sqlFileName;

    private StreamRepository sr = null;

    //The data-source for this repository
    protected DataSourceSelector datasources;
    protected DataSourceComponent datasource;
    protected String datasourceName;

    // Contains all of the sql strings for this component.
    protected SqlResources sqlQueries;


    public void contextualize(final Context context)
            throws ContextException {
        this.context = context;
    }

    public void configure(Configuration conf) throws ConfigurationException 
{
        getLogger().debug(this.getClass().getName() + ".configure()");

        destination = conf.getAttribute("destinationURL");
        // normalise the destination, to simplify processing.
        if ( ! destination.endsWith("/") ) {
            destination += "/";
        }
        // Parse the DestinationURL for the name of the datasource,
        // the table to use, and the (optional) repository Key.
        // Split on "/", starting after "db://"
        List urlParams = new ArrayList();
        int start = 5;
        if (destination.startsWith("dbfile")) {
            //this is dbfile:// instead of db://
            start += 4;
        }
        int end = destination.indexOf('/', start);
        while ( end > -1 ) {
            urlParams.add(destination.substring(start, end));
            start = end + 1;
            end = destination.indexOf('/', start);
        }

        // Build SqlParameters and get datasource name from URL parameters
        if (urlParams.size() == 0) {
            throw new ConfigurationException
                ("Malformed destinationURL - Must be of the format '" +
                 "db://<data-source>[/<table>[/<repositoryName>]]'.  Was 
passed " + conf.getAttribute("destinationURL"));
        }
        if (urlParams.size() >= 1) {
            datasourceName = (String)urlParams.get(0);
        }
        if (urlParams.size() >= 2) {
            tableName = (String)urlParams.get(1);
        }
        if (urlParams.size() >= 3) {
            repositoryName = "";
            for (int i = 2; i < urlParams.size(); i++) {
                if (i >= 3) {
                    repositoryName += '/';
                }
                repositoryName += (String)urlParams.get(i);
            }
        }

        getLogger().debug("Parsed URL: table = '" + tableName +
                          "', repositoryName = '" + repositoryName + "'");

        filestore = conf.getChild("filestore").getValue(null);
        sqlFileName = conf.getChild("sqlFile").getValue();
        if (!sqlFileName.startsWith("file://")) {
            throw new ConfigurationException
                ("Malformed sqlFile - Must be of the format 
'file://<filename>'.");
        }
    }

    public void compose( final ComponentManager componentManager )
        throws ComponentException {
        getLogger().debug(this.getClass().getName() + ".compose()");

        // Get the DataSourceSelector block
        datasources = (DataSourceSelector)componentManager.lookup( 
DataSourceSelector.ROLE );

        try {
            if (filestore != null) {
                Store store = (Store)componentManager.
                        
lookup("org.apache.avalon.cornerstone.services.store.Store");
                //prepare Configurations for stream repositories
                DefaultConfiguration streamConfiguration
                    = new DefaultConfiguration( "repository",
                                                
"generated:JDBCMailRepository.compose()" );

                streamConfiguration.setAttribute( "destinationURL", 
filestore );
                streamConfiguration.setAttribute( "type", "STREAM" );
                streamConfiguration.setAttribute( "model", "SYNCHRONOUS" );
                sr = (StreamRepository) store.select(streamConfiguration);

                getLogger().debug("Got filestore for JdbcMailRepository: " + 
filestore);
            }

            lock = new Lock();
            getLogger().debug(this.getClass().getName() + " created 
according to " + destination);
        } catch (Exception e) {
            final String message = "Failed to retrieve Store component:" + 
e.getMessage();
            getLogger().error(message, e);
            e.printStackTrace();
            throw new ComponentException(message, e);
        }
    }

    /**
     * Initialises the JDBC repository.
     * 1) Tests the connection to the database.
     * 2) Loads SQL strings from the SQL definition file,
     *     choosing the appropriate SQL for this connection,
     *     and performing paramter substitution,
     * 3) Initialises the database with the required tables, if necessary.
     *
     */
    public void initialize() throws Exception {
        getLogger().debug(this.getClass().getName() + ".initialize()");

        // Sam. Oracle code implementation of BLOB binary type
        // START
        // Register the Oracle JDBC driver
        DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
        // END

        // Get the data-source required.
        datasource = 
(DataSourceComponent)datasources.select(datasourceName);

        // Test the connection to the database, by getting the 
DatabaseMetaData.
        Connection conn = datasource.getConnection();

        try {
            // Initialise the sql strings.
            String fileName = sqlFileName.substring("file://".length());
            fileName = ((BlockContext)context).getBaseDirectory() +
                        File.separator + fileName;
            File sqlFile = (new File(fileName)).getCanonicalFile();

            String resourceName = 
"org.apache.james.mailrepository.JDBCMailRepository";

            getLogger().debug("Reading SQL resources from file: " +
                              sqlFile.getAbsolutePath() + ", section " +
                              this.getClass().getName() + ".");

            // Build the statement parameters
            Map sqlParameters = new HashMap();
            if (tableName != null) {
                sqlParameters.put("table", tableName);
            }
            if (repositoryName != null) {
                sqlParameters.put("repository", repositoryName);
            }

            sqlQueries = new SqlResources();
            sqlQueries.init(sqlFile, this.getClass().getName(),
                            conn, sqlParameters);

            // Check if the required table exists. If not, create it.
            DatabaseMetaData dbMetaData = conn.getMetaData();
            // Need to ask in the case that identifiers are stored, ask the 
DatabaseMetaInfo.
            // Try UPPER, lower, and MixedCase, to see if the table is 
there.
            if (! ( tableExists(dbMetaData, tableName) ||
                    tableExists(dbMetaData, tableName.toUpperCase()) ||
                    tableExists(dbMetaData, tableName.toLowerCase()) ))  {
                // Users table doesn't exist - create it.
                PreparedStatement createStatement =
                    
conn.prepareStatement(sqlQueries.getSqlString("createTable", true));
                createStatement.execute();
                createStatement.close();

                getLogger().info("JdbcMailRepository: Created table '" +
                                 tableName + "'.");
            }
        } finally {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private boolean tableExists(DatabaseMetaData dbMetaData, String 
tableName)
        throws SQLException {
        ResultSet rsTables = dbMetaData.getTables(null, null, tableName, 
null);
        boolean found = rsTables.next();
        rsTables.close();
        return found;
    }

    public synchronized boolean unlock(String key) {
        if (lock.unlock(key)) {
            notifyAll();
            return true;
        } else {
            return false;
        }
    }

    public synchronized boolean lock(String key) {
        if (lock.lock(key)) {
            //notifyAll();
            return true;
        } else {
            return false;
        }
    }

    public void store(MailImpl mc) {
        //System.err.println("storing " + mc.getName());
        Connection conn = null;
        try {
            conn = datasource.getConnection();

            //Need to determine whether need to insert this record, or 
update it.

            //Begin a transaction
            conn.setAutoCommit(false);

            PreparedStatement checkMessageExists =
                
conn.prepareStatement(sqlQueries.getSqlString("checkMessageExistsSQL", 
true));
            checkMessageExists.setString(1, mc.getName());
            checkMessageExists.setString(2, repositoryName);
            ResultSet rsExists = checkMessageExists.executeQuery();
            boolean exists = rsExists.next() && rsExists.getInt(1) > 0;
            rsExists.close();
            checkMessageExists.close();

            if (exists) {
                //Update the existing record
                PreparedStatement updateMessage =
                    
conn.prepareStatement(sqlQueries.getSqlString("updateMessageSQL", true));
                updateMessage.setString(1, mc.getState());
                updateMessage.setString(2, mc.getErrorMessage());
                if (mc.getSender() == null) {
                    updateMessage.setNull(3, java.sql.Types.VARCHAR);
                } else {
                    updateMessage.setString(3, mc.getSender().toString());
                }
                StringBuffer recipients = new StringBuffer();
                for (Iterator i = mc.getRecipients().iterator(); 
i.hasNext(); ) {
                    recipients.append(i.next().toString());
                    if (i.hasNext()) {
                        recipients.append("\r\n");
                    }
                }
                updateMessage.setString(4, recipients.toString());
                updateMessage.setString(5, mc.getRemoteHost());
                updateMessage.setString(6, mc.getRemoteAddr());
                updateMessage.setTimestamp(7, new 
java.sql.Timestamp(mc.getLastUpdated().getTime()));
                updateMessage.setString(8, mc.getName());
                updateMessage.setString(9, repositoryName);
                updateMessage.execute();
                updateMessage.close();

                //Determine whether the message body has changed, and 
possibly avoid
                //  updating the database.
                MimeMessage messageBody = mc.getMessage();
                boolean saveBody = false;
                if (messageBody instanceof MimeMessageWrapper) {
                    MimeMessageWrapper message = 
(MimeMessageWrapper)messageBody;
                    saveBody = message.isModified();
                } else {
                    saveBody = true;
                }

                if (saveBody) {
                    // Sam. Oracle code implementation of BLOB binary type
                    // START
                    /*updateMessage =
                          
conn.prepareStatement(sqlQueries.getSqlString("updateMessageBodySQL", 
true));*/
                    // Must first retrieve BLOB locator for message_body 
field
                    // in Oracle database prior to value insertion.
                    PreparedStatement readMessageBody =
                      
conn.prepareStatement(sqlQueries.getSqlString("retrieveMessageBodySQL", 
true));
                    readMessageBody.setString(1, mc.getName());
                    readMessageBody.setString(2, repositoryName);
                    ResultSet rset = readMessageBody.executeQuery();

                    if (rset.next())
                    {
                      // retrieve the LOB locator from the ResultSet
                      BLOB messageBody_blob = 
((OracleResultSet)rset).getBLOB(1);

                      OraclePreparedStatement ops =
                        (OraclePreparedStatement) conn.prepareStatement(
                        sqlQueries.getSqlString("updateMessageBodySQL", 
true));
                    // END

                      ByteArrayOutputStream headerOut = new 
ByteArrayOutputStream();
                      OutputStream bodyOut = null;
                      if (sr == null) {
                          //If there is no filestore, use the byte array to 
store headers
                          //  and the body
                          bodyOut = headerOut;
                      } else {
                          //Store the body in the stream repository
                          bodyOut = sr.put(mc.getName());
                      }

                      //Write the message to the headerOut and bodyOut.  
bodyOut goes straight to the file
                      MimeMessageWrapper.writeTo(messageBody, headerOut, 
bodyOut);
                      bodyOut.close();

                      //Store the headers in the database

                      // Sam. Oracle code implementation of BLOB binary type
                      // START
                      // Start writing to the start of the LOB. ie. 
overwrite.
                      // Write the contents of the buffer into position pos 
of the output LOB:
                      messageBody_blob.putBytes(0, headerOut.toByteArray());
                      ops.setBlob(1, messageBody_blob);
                      ops.setString(2, mc.getName());
                      ops.setString(3, repositoryName);
                      ops.execute();
                      ops.close();
                  } // End if {rset.next()}

                  readMessageBody.close();
                  rset.close();
                  // END
                }
            } else {
                //Insert the record into the database

                // Sam. Oracle code implementation of BLOB binary type
                // START
                /*PreparedStatement insertMessage =
                    
conn.prepareStatement(sqlQueries.getSqlString("insertMessageSQL", true));*/
                OraclePreparedStatement insertMessage =
                  (OraclePreparedStatement) conn.prepareStatement(
                  sqlQueries.getSqlString("insertMessageSQL", true));
                // END

                insertMessage.setString(1, mc.getName());
                insertMessage.setString(2, repositoryName);
                insertMessage.setString(3, mc.getState());
                insertMessage.setString(4, mc.getErrorMessage());
                if (mc.getSender() == null) {
                    insertMessage.setNull(5, java.sql.Types.VARCHAR);
                } else {
                    insertMessage.setString(5, mc.getSender().toString());
                }
                StringBuffer recipients = new StringBuffer();
                for (Iterator i = mc.getRecipients().iterator(); 
i.hasNext(); ) {
                    recipients.append(i.next().toString());
                    if (i.hasNext()) {
                        recipients.append("\r\n");
                    }
                }
                insertMessage.setString(6, recipients.toString());
                insertMessage.setString(7, mc.getRemoteHost());
                insertMessage.setString(8, mc.getRemoteAddr());
                insertMessage.setTimestamp(9, new 
java.sql.Timestamp(mc.getLastUpdated().getTime()));
                MimeMessage messageBody = mc.getMessage();

                ByteArrayOutputStream headerOut = new 
ByteArrayOutputStream();
                OutputStream bodyOut = null;
                if (sr == null) {
                    //If there is no sr, then use the same byte array to 
hold the headers
                    //  and the body
                    bodyOut = headerOut;
                } else {
                    //Store the body in the file system.
                    bodyOut = sr.put(mc.getName());
                }

                //Write the message to the headerOut and bodyOut.  bodyOut 
goes straight to the file
                MimeMessageWrapper.writeTo(messageBody, headerOut, bodyOut);
                bodyOut.close();

                //Store the headers in the database
                // Sam. Oracle code implementation of BLOB binary type
                // START
                //insertMessage.setBytes(10, headerOut.toByteArray());
                insertMessage.setObject(10, headerOut.toByteArray());
                insertMessage.execute();
                insertMessage.close();
                // END
            } // End if {(exists)}

            conn.commit();
            conn.setAutoCommit(true);

            synchronized (this) {
                notifyAll();
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("Exception caught while storing mail 
Container: " + e);
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException sqle) {
                    //ignore
                }
            }
        }
    }

    public MailImpl retrieve(String key) {
        //System.err.println("retrieving " + key);
        Connection conn = null;
        try {
            conn = datasource.getConnection();

            PreparedStatement retrieveMessage =
                
conn.prepareStatement(sqlQueries.getSqlString("retrieveMessageSQL", true));
            retrieveMessage.setString(1, key);
            retrieveMessage.setString(2, repositoryName);
            ResultSet rsMessage = retrieveMessage.executeQuery();
            if (!rsMessage.next()) {
                throw new RuntimeException("Did not find a record " + key + 
" in " + repositoryName);
            }
            MailImpl mc = new MailImpl();
            mc.setName(key);
            mc.setState(rsMessage.getString(1));
            mc.setErrorMessage(rsMessage.getString(2));
            String sender = rsMessage.getString(3);
            if (sender == null) {
                mc.setSender(null);
            } else {
                mc.setSender(new MailAddress(sender));
            }
            StringTokenizer st = new StringTokenizer(rsMessage.getString(4), 
"\r\n", false);
            Set recipients = new HashSet();
            while (st.hasMoreTokens()) {
                recipients.add(new MailAddress(st.nextToken()));
            }
            mc.setRecipients(recipients);
            mc.setRemoteHost(rsMessage.getString(5));
            mc.setRemoteAddr(rsMessage.getString(6));
            mc.setLastUpdated(rsMessage.getTimestamp(7));

            MimeMessageJDBCSource source = new MimeMessageJDBCSource(this, 
key, sr);
            MimeMessageWrapper message = new MimeMessageWrapper(source);
            mc.setMessage(message);
            rsMessage.close();
            retrieveMessage.close();
            return mc;
        } catch (SQLException sqle) {
            synchronized (System.err) {
                System.err.println("Error retrieving message");
                System.err.println(sqle.getMessage());
                System.err.println(sqle.getErrorCode());
                System.err.println(sqle.getSQLState());
                System.err.println(sqle.getNextException());
                sqle.printStackTrace();
            }
            throw new RuntimeException("Exception while retrieving mail: " + 
sqle.getMessage());
        } catch (Exception me) {
            me.printStackTrace();
            throw new RuntimeException("Exception while retrieving mail: " + 
me.getMessage());
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException sqle) {
                    //ignore
                }
            }
        }
    }

    public void remove(MailImpl mail) {
        remove(mail.getName());
    }

    public void remove(String key) {
        //System.err.println("removing " + key);
        if (lock(key)) {
            Connection conn = null;
            try {
                conn = datasource.getConnection();
                PreparedStatement removeMessage =
                    
conn.prepareStatement(sqlQueries.getSqlString("removeMessageSQL", true));
                removeMessage.setString(1, key);
                removeMessage.setString(2, repositoryName);
                removeMessage.execute();
                removeMessage.close();

                if (sr != null) {
                    sr.remove(key);
                }
            } catch (Exception me) {
                throw new RuntimeException("Exception while removing mail: " 
+ me.getMessage());
            } finally {
                if (conn != null) {
                    try {
                        conn.close();
                    } catch (SQLException sqle) {
                        //ignore
                    }
                }
                unlock(key);
            }
        }
    }

    public Iterator list() {
        //System.err.println("listing messages");
        Connection conn = null;
        try {
            conn = datasource.getConnection();
            PreparedStatement listMessages =
                
conn.prepareStatement(sqlQueries.getSqlString("listMessagesSQL", true));
            listMessages.setString(1, repositoryName);
            ResultSet rsListMessages = listMessages.executeQuery();

            List messageList = new ArrayList();
            while (rsListMessages.next()) {
                messageList.add(rsListMessages.getString(1));
            }
            rsListMessages.close();
            listMessages.close();
            return messageList.iterator();
        } catch (Exception me) {
            me.printStackTrace();
            throw new RuntimeException("Exception while listing mail: " + 
me.getMessage());
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException sqle) {
                    //ignore
                }
            }
        }
    }

    protected Connection getConnection() throws SQLException {
        return datasource.getConnection();
    }

    public boolean equals(Object obj) {
        if (!(obj instanceof JDBCMailRepository)) {
            return false;
        }
        JDBCMailRepository repository = (JDBCMailRepository)obj;
        return repository.tableName.equals(tableName) && 
repository.repositoryName.equals(repositoryName);
    }
}


Second, here's the code for MimeMessageJDBCSource:


/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.james.mailrepository;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.apache.james.core.MimeMessageSource;
import org.apache.avalon.cornerstone.services.store.StreamRepository;
import org.apache.james.util.SqlResources;
import java.lang.Long;
// Sam. Oracle code implementation of BLOB binary type
// Need to import oracle sql packages.
// START
//needed for new CLOB and BLOB classes
import oracle.sql.*;
import oracle.jdbc.driver.*;
// END

/**
* This class points to a specific message in a repository.  This will return 
an
* InputStream to the JDBC field/record, possibly sequenced with the file 
stream.
*/
public class MimeMessageJDBCSource extends MimeMessageSource {

    //Define how to get to the data
    JDBCMailRepository repository = null;
    String key = null;
    StreamRepository sr = null;

    String retrieveMessageBodySQL = null;
    String retrieveMessageBodySizeSQL = null;

    /**
     * Construct a MimeMessageSource based on a JDBC repository, a key, and 
a
     * stream repository (where we might store the message body)
     */
    public MimeMessageJDBCSource(JDBCMailRepository repository,
            String key, StreamRepository sr) throws IOException {
        if (repository == null) {
            throw new IOException("Repository is null");
        }
        if (key == null) {
            throw new IOException("Message name (key) was not defined");
        }
        this.repository = repository;
        this.key = key;
        this.sr = sr;

        // Sam. Oracle code implementation of BLOB binary type
        // START
        try
        {
          // Register the Oracle JDBC driver
          DriverManager.registerDriver(new 
oracle.jdbc.driver.OracleDriver());
        }
        catch (Exception e)
        {
          e.printStackTrace();
        }
        // END

        retrieveMessageBodySQL =
            repository.sqlQueries.getSqlString("retrieveMessageBodySQL", 
true);
        // this is optional
        retrieveMessageBodySizeSQL =
            
repository.sqlQueries.getSqlString("retrieveMessageBodySizeSQL");
    }

    /**
     * Return the input stream to the database field and then the file 
stream.  This should
     * be smart enough to work even if the file does not exist.  This is to 
support
     * a repository with the entire message in the database, which is how 
James 1.2 worked.
     */
    public synchronized InputStream getInputStream() throws IOException {
        try {
            Connection conn = repository.getConnection();

            PreparedStatement retrieveMessageStream = 
conn.prepareStatement(retrieveMessageBodySQL);
            retrieveMessageStream.setString(1, key);
            retrieveMessageStream.setString(2, repository.repositoryName);
            ResultSet rsRetrieveMessageStream = 
retrieveMessageStream.executeQuery();

            if (!rsRetrieveMessageStream.next()) {
                throw new IOException("Could not find message");
            }

            // Sam. Oracle code implementation of BLOB binary type
            // START
            // retrieve the LOB locator from the ResultSet
            BLOB messageBody_blob = 
((OracleResultSet)rsRetrieveMessageStream).getBLOB(1);

            // read the blob into a byte array
            Long lval = new Long(messageBody_blob.length());
            //byte[] headers = rsRetrieveMessageStream.getBytes(1);
            byte[] headers = messageBody_blob.getBytes(1, lval.intValue());
            // END
            rsRetrieveMessageStream.close();
            retrieveMessageStream.close();
            conn.close();

            InputStream in = new ByteArrayInputStream(headers);
            try {
                if (sr != null) {
                    in = new SequenceInputStream(in, sr.get(key));
                }
            } catch (Exception e) {
                //ignore this... either sr is null, or the file does not 
exist
                // or something else
            }
            return in;
        } catch (SQLException sqle) {
            throw new IOException(sqle.toString());
        }
    }

    /**
     * Runs a custom SQL statement to check the size of the message body
     */
    public synchronized long getMessageSize() throws IOException {
        if (retrieveMessageBodySizeSQL == null) {
            //There was no SQL statement for this repository... figure it 
out the hard way
            return super.getMessageSize();
        }

        try {
            Connection conn = repository.getConnection();

            PreparedStatement retrieveMessageSize = 
conn.prepareStatement(retrieveMessageBodySizeSQL);
            retrieveMessageSize.setString(1, key);
            retrieveMessageSize.setString(2, repository.repositoryName);
            ResultSet rsRetrieveMessageSize = 
retrieveMessageSize.executeQuery();

            if (!rsRetrieveMessageSize.next()) {
                throw new IOException("Could not find message");
            }

            long size = rsRetrieveMessageSize.getLong(1);
            rsRetrieveMessageSize.close();
            retrieveMessageSize.close();
            conn.close();

            try {
                if (sr != null) {
                    InputStream in = sr.get(key);
                    int len = 0;
                    byte[] block = new byte[1024];
                    while ((len = in.read(block)) > -1) {
                        size += len;
                    }
                    in.close();
                }
            } catch (Exception e) {
                //ignore this... either sr is null, or the file does not 
exist
                // or something else
            }
            return size;
        } catch (SQLException sqle) {
            throw new IOException(sqle.toString());
        }
    }

    /**
     * Check to see whether this is the same repository and the same key
     */
    public boolean equals(Object obj) {
        if (obj instanceof MimeMessageJDBCSource) {
            MimeMessageJDBCSource source = (MimeMessageJDBCSource)obj;
            return source.key.equals(key) && 
source.repository.equals(repository);
        }
        return false;
    }
}

Also, you'll need to place the two oracle classes I mentioned to you into 
the lib directory of James installation.

And that is it!

Please incorporate the following credits to the effected sources which I 
myself have implemented into the next release of James:

@author Samuel Sadek <[EMAIL PROTECTED], [EMAIL PROTECTED], 
[EMAIL PROTECTED]>

Thank you.

One word of note, Serge, there are several versions of Oracle out there, 
need to provide in next release of James, potential set of Oracle JDBC 
driver classes, especially if it has changed for Oracle 9i.

>Sorry, I should have been clearer.  Can you provide the Oracle workaround 
>to
>support a BINARY LOB?  We can, but I'd prefer to not apply the text-based
>shortcut because I expect it will cause other users problems by corrupting
>their messages.

>Serge Knystautas
>Loki Technologies - Unstoppable Websites
>http://www.lokitech.com/
----- Original Message -----
From: "Samuel Sadek" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Sunday, February 24, 2002 7:32 PM
Subject: Re: How to make James work with Oracle database?


>Serge,
>
>The class is JamesJDBCMailRepository in method (public void store(MailImpl
>mc)):
>
>Scan for the start/end markers to find modified code. Remember I just
simply
>copied the contents of the byte array output into a string and written
this
>directly via setString into the message_body field within inbox table in
>Oracle 8.1.7.



_________________________________________________________________
Chat with friends online, try MSN Messenger: http://messenger.msn.com


--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to