001    /*
002     * Copyright 2007 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.apache.ojb.broker.platforms;
017    
018    import java.io.ByteArrayInputStream;
019    import java.io.InputStreamReader;
020    import java.io.Reader;
021    import java.io.StringReader;
022    import java.sql.CallableStatement;
023    import java.sql.Connection;
024    import java.sql.PreparedStatement;
025    import java.sql.SQLException;
026    import java.sql.Types;
027    
028    import org.apache.ojb.broker.query.LikeCriteria;
029    
030    /**
031     * @author Kuali Rice Team (rice.collab@kuali.org)
032     */
033    public class PlatformMySQLImpl extends PlatformDefaultImpl
034    {
035        private static final String LAST_INSERT = "SELECT LAST_INSERT_ID() FROM ";
036        private static final String LIMIT = " LIMIT 1";
037        
038        /*
039             * @see DatabasePlatform#setObjectForStatement(PreparedStatement, int, Object, int)
040             */
041        public void setObjectForStatement(PreparedStatement ps, int index, Object value, int sqlType) throws SQLException
042        {
043            switch (sqlType)
044            {
045                case Types.BIT :
046                    ps.setObject(index, value);
047                    break;
048    
049                case Types.BLOB :
050                case Types.LONGVARBINARY :
051                case Types.VARBINARY :
052                    if (value instanceof byte[])
053                    {
054                        byte buf[] = (byte[]) value;
055                        ByteArrayInputStream inputStream = new ByteArrayInputStream(buf);
056                        ps.setBinaryStream(index, inputStream, buf.length);
057    
058                        break;
059                    }
060    
061                case Types.CLOB :
062                    Reader reader = null;
063                    int length = 0;
064    
065                    if (value instanceof String)
066                    {
067                        reader = new StringReader((String) value);
068                        length = (((String) value)).length();
069                    }
070                    else if (value instanceof char[])
071                    {
072                        String string = new String((char[])value);
073                        reader = new StringReader(string);
074                        length = string.length();
075                    }
076                    else if (value instanceof byte[])
077                    {
078                        byte buf[] = (byte[]) value;
079                        ByteArrayInputStream inputStream = new ByteArrayInputStream(buf);
080                        reader = new InputStreamReader(inputStream);
081                    }
082    
083                    ps.setCharacterStream(index, reader, length);
084                    break;
085    
086                default :
087                    super.setObjectForStatement(ps, index, value, sqlType);
088    
089            }
090        }
091        /**
092             * Get join syntax type for this RDBMS - one on of the constants from
093             * JoinSyntaxType interface
094             */
095        public byte getJoinSyntaxType()
096        {
097            return SQL92_NOPAREN_JOIN_SYNTAX;
098        }
099    
100        public String getLastInsertIdentityQuery(String tableName)
101        {
102            return LAST_INSERT + tableName + LIMIT;
103        }
104    
105        /*
106             * (non-Javadoc)
107             * 
108             * @see org.apache.ojb.broker.platforms.Platform#addPagingSql(java.lang.StringBuffer)
109             */
110        public void addPagingSql(StringBuffer anSqlString)
111        {
112            anSqlString.append(" LIMIT ?,?");
113        }
114    
115        /* (non-Javadoc)
116         * @see org.apache.ojb.broker.platforms.Platform#createSequenceQuery(String)
117         */
118        public String createSequenceQuery(String sequenceName)
119        {
120            return "insert into ojb_nextval_seq (seq_name) " + 
121                            "values ('" + sequenceName + "')";
122        }
123    
124        /* (non-Javadoc)
125         * @see org.apache.ojb.broker.platforms.Platform#nextSequenceQuery(String)
126         */
127        public String nextSequenceQuery(String sequenceName)
128        {
129            return "select ojb_nextval_func ('" + sequenceName + "')";
130        }
131    
132        /* (non-Javadoc)
133         * @see org.apache.ojb.broker.platforms.Platform#dropSequenceQuery(String)
134         */
135        public String dropSequenceQuery(String sequenceName)
136        {
137            return "delete from ojb_nextval_seq where seq_name='" + 
138                            sequenceName + "'";
139        }
140        
141        /* (non-Javadoc)
142         * Copied over from the OJB implementations for Informix
143         */
144        public CallableStatement prepareNextValProcedureStatement (Connection con,
145                                                            String procedureName, String sequenceName) throws
146                                                            PlatformException
147        {
148            try {
149                    String sp = " { call " + procedureName + " (?,?) } ";                   
150                    CallableStatement cs = con.prepareCall(sp);
151                    cs.registerOutParameter(1, Types.BIGINT);
152                    cs.setString(2, sequenceName);
153                    return cs;
154            } catch (Exception e) {
155                    throw new PlatformException(e);
156            }
157        }
158        
159        /*
160             * (non-Javadoc)
161             * 
162             * @see org.apache.ojb.broker.platforms.Platform#supportsPaging()
163             */
164        public boolean supportsPaging()
165        {
166            return true;
167        }
168    
169        /**
170         * @see org.apache.ojb.broker.platforms.Platform#concatenate(java.lang.String[])
171         */
172        public String concatenate(String[] theColumns)
173        {
174            if (theColumns.length == 1)
175            {
176                return theColumns[0];
177            }
178            
179            StringBuffer buf = new StringBuffer();
180            
181            buf.append("concat(");
182            for (int i = 0; i < theColumns.length; i++)
183            {
184                if (i > 0)
185                {
186                    buf.append(",");
187                }
188                buf.append(theColumns[i]);
189            }
190    
191            buf.append(")");
192            return buf.toString();
193        }    
194        
195        /**
196         * @see org.apache.ojb.broker.platforms.Platform#getEscapeClause(org.apache.ojb.broker.query.LikeCriteria)
197         */
198        public String getEscapeClause(LikeCriteria aCriteria)
199        {
200            if (LikeCriteria.getEscapeCharacter() != LikeCriteria.DEFAULT_ESCPAPE_CHARACTER)  
201            {
202                // the default escape character is \, so there's no need for an escape clause
203                return super.getEscapeClause(aCriteria);
204            }
205            return "";
206        }    
207    }