001/*
002 * HA-JDBC: High-Availability JDBC
003 * Copyright (C) 2012  Paul Ferraro
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Lesser General Public License as published by
007 * the Free Software Foundation, either version 3 of the License, or
008 * (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU Lesser General Public License for more details.
014 *
015 * You should have received a copy of the GNU Lesser General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018package net.sf.hajdbc.dialect.h2;
019
020import java.sql.DatabaseMetaData;
021import java.sql.ResultSet;
022import java.sql.SQLException;
023import java.sql.Statement;
024import java.util.Arrays;
025import java.util.Collection;
026import java.util.Collections;
027import java.util.HashSet;
028import java.util.LinkedList;
029import java.util.List;
030import java.util.Set;
031
032import net.sf.hajdbc.SequenceProperties;
033import net.sf.hajdbc.SequencePropertiesFactory;
034import net.sf.hajdbc.SequenceSupport;
035import net.sf.hajdbc.dialect.StandardDialect;
036import net.sf.hajdbc.util.Resources;
037
038/**
039 * Dialect for <a href="http://www.h2database.com">H2 Database Engine</a>.
040 * @author Paul Ferraro
041 */
042public class H2Dialect extends StandardDialect
043{
044        private static final Set<Integer> failureCodes = new HashSet<Integer>(Arrays.asList(90013, 90030, 90046, 90067, 90100, 90108, 90117, 90121));
045        
046        /**
047         * {@inheritDoc}
048         * @see net.sf.hajdbc.dialect.StandardDialect#vendorPattern()
049         */
050        @Override
051        protected String vendorPattern()
052        {
053                return "h2";
054        }
055
056        /**
057         * @see net.sf.hajdbc.dialect.StandardDialect#executeFunctionFormat()
058         */
059        @Override
060        protected String executeFunctionFormat()
061        {
062                return "CALL {0}";
063        }
064
065        /**
066         * {@inheritDoc}
067         * @see net.sf.hajdbc.dialect.StandardDialect#getSequenceSupport()
068         */
069        @Override
070        public SequenceSupport getSequenceSupport()
071        {
072                return this;
073        }
074
075        @Override
076        public Collection<SequenceProperties> getSequences(DatabaseMetaData metaData, SequencePropertiesFactory factory) throws SQLException
077        {
078                Statement statement = metaData.getConnection().createStatement();
079                
080                try
081                {
082                        ResultSet resultSet = statement.executeQuery("SELECT SEQUENCE_SCHEMA, SEQUENCE_NAME, INCREMENT FROM INFORMATION_SCHEMA.SEQUENCES");
083                        
084                        List<SequenceProperties> sequences = new LinkedList<SequenceProperties>();
085                        
086                        while (resultSet.next())
087                        {
088                                sequences.add(factory.createSequenceProperties(resultSet.getString(1), resultSet.getString(2), resultSet.getInt(3)));
089                        }
090                        
091                        return sequences;
092                }
093                finally
094                {
095                        Resources.close(statement);
096                }
097        }
098
099        /**
100         * Deferrability clause is not supported.
101         * @see net.sf.hajdbc.dialect.StandardDialect#createForeignKeyConstraintFormat()
102         */
103        @Override
104        protected String createForeignKeyConstraintFormat()
105        {
106                return "ALTER TABLE {1} ADD CONSTRAINT {0} FOREIGN KEY ({2}) REFERENCES {3} ({4}) ON DELETE {5,choice,0#CASCADE|1#RESTRICT|2#SET NULL|3#NO ACTION|4#SET DEFAULT} ON UPDATE {6,choice,0#CASCADE|1#RESTRICT|2#SET NULL|3#NO ACTION|4#SET DEFAULT}";
107        }
108
109        /**
110         * @see net.sf.hajdbc.dialect.StandardDialect#currentDatePattern()
111         */
112        @Override
113        protected String currentDatePattern()
114        {
115                return "(?<=\\W)CURRENT_DATE(?:\\s*\\(\\s*\\))?(?=\\W)|(?<=\\W)CURDATE\\s*\\(\\s*\\)|(?<=\\W)SYSDATE(?=\\W)|(?<=\\W)TODAY(?=\\W)";
116        }
117
118        /**
119         * @see net.sf.hajdbc.dialect.StandardDialect#currentTimePattern()
120         */
121        @Override
122        protected String currentTimePattern()
123        {
124                return "(?<=\\W)CURRENT_TIME(?:\\s*\\(\\s*\\))?(?=\\W)|(?<=\\W)CURTIME\\s*\\(\\s*\\)";
125        }
126
127        /**
128         * @see net.sf.hajdbc.dialect.StandardDialect#currentTimestampPattern()
129         */
130        @Override
131        protected String currentTimestampPattern()
132        {
133                return "(?<=\\W)CURRENT_TIMESTAMP(?:\\s*\\(\\s*\\d*\\s*\\))?(?=\\W)|(?<=\\W)NOW\\s*\\(\\s*\\d*\\s*\\)";
134        }
135
136        /**
137         * @see net.sf.hajdbc.dialect.StandardDialect#randomPattern()
138         */
139        @Override
140        protected String randomPattern()
141        {
142                return "(?<=\\W)RAND\\s*\\(\\s*\\d*\\s*\\)";
143        }
144
145        /**
146         * {@inheritDoc}
147         * @see net.sf.hajdbc.dialect.StandardDialect#getDefaultSchemas(java.sql.DatabaseMetaData)
148         */
149        @Override
150        public List<String> getDefaultSchemas(DatabaseMetaData metaData)
151        {
152                return Collections.singletonList("PUBLIC");
153        }
154
155        @Override
156        protected boolean indicatesFailure(int code)
157        {
158                return failureCodes.contains(code);
159        }
160}