001    package org.apache.ojb.broker.platforms;
002    
003    /* Copyright 2002-2005 The Apache Software Foundation
004     *
005     * Licensed under the Apache License, Version 2.0 (the "License");
006     * you may not use this file except in compliance with the License.
007     * You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    import java.io.ByteArrayInputStream;
019    import java.math.BigDecimal;
020    import java.sql.PreparedStatement;
021    import java.sql.ResultSet;
022    import java.sql.SQLException;
023    import java.sql.Statement;
024    import java.sql.Types;
025    
026    import org.apache.ojb.broker.query.LikeCriteria;
027    import org.apache.ojb.broker.util.logging.LoggerFactory;
028    
029    /**
030     * @author <a href="mailto:jbraeuchi@gmx.ch">Jakob Braeuchi</a>
031     * @version $Id: PlatformMsAccessImpl.java,v 1.1 2007-08-24 22:17:35 ewestfal Exp $
032     */
033    public class PlatformMsAccessImpl extends PlatformDefaultImpl
034    {
035        /**
036         * @see Platform#setObjectForStatement(PreparedStatement, int, Object, int)
037         */
038        public void setObjectForStatement(PreparedStatement ps, int index, Object value, int sqlType)
039            throws SQLException
040        {
041            if (sqlType == Types.DECIMAL)
042            {
043                ps.setBigDecimal(index, (BigDecimal) value);
044            }
045            else if (sqlType == Types.FLOAT)
046            {
047                // this is because in repository_junit.xml price field is a double in the Article class
048                // but repository maps it to a sql type of FLOAT (any my ODBC/JDBC bridge/driver cannot
049                // cope with this conversion...possibility of a truncation error heer as well...
050                if (value instanceof Double)
051                {
052                    ps.setDouble(index, ((Double) value).doubleValue());
053                }
054                else
055                {
056                    super.setObjectForStatement(ps, index, value, sqlType);
057                }
058            }
059            // patch by Ralph Brandes to allow writing to memo fields
060            else if (sqlType == Types.LONGVARCHAR)
061            {
062                if (value instanceof String)
063                {
064                    String s = (String) value;
065                    // ps.setCharacterStream(index, new StringReader(s), s.length());
066                    // for MSACCESS :                
067                    byte[] bytes = s.getBytes();
068                    ByteArrayInputStream bais = new ByteArrayInputStream(bytes);                
069                    ps.setAsciiStream(index, bais, bytes.length);
070                }
071                else
072                {
073                    super.setObjectForStatement(ps, index, value, sqlType);
074                }
075            }
076            // patch by Tino Sch�llhorn 
077            // Current ODBC-Implementation for Access (I use ODBC 4.0.xxxx) does not 
078            // support the conversion of LONG values. 
079            // Error is : "Optional feature not implemented"
080            // So I try to pass the LONG-value as an Integer even though it might be possible
081            // that the conversion fails - but I don't think that is an issues with Access anyway.
082            else if (value instanceof Long)
083            {
084                ps.setInt(index,((Long)value).intValue());
085            }
086            else
087            {
088                super.setObjectForStatement(ps, index, value, sqlType);        
089            }
090        }        
091    
092        /**
093         * @see Platform#beforeStatementClose(Statement stmt, ResultSet rs)
094         */
095        public void beforeStatementClose(Statement stmt, ResultSet rs) throws PlatformException
096        {
097            if (rs != null)
098            {
099                try
100                {
101                    rs.close();
102                }
103                catch (SQLException e)
104                {
105                    LoggerFactory.getDefaultLogger().warn(
106                        "Resultset closing failed (can be ignored for MsAccess)");
107                }
108            }
109        }
110        
111        /**
112         * Answer the Character for Concatenation
113         */
114        protected String getConcatenationCharacter()
115        {
116            return "&";
117        }    
118        
119        /**
120         * @see org.apache.ojb.broker.platforms.Platform#getEscapeClause(org.apache.ojb.broker.query.LikeCriteria)
121         */
122        public String getEscapeClause(LikeCriteria aCriteria)
123        {
124            // TODO: implement ms-access escaping
125            return "";  
126        }
127    }