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.hsqldb;
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.hsqldb.org">HSQLDB</a>.
040 * 
041 * @author  Paul Ferraro
042 * @since   1.1
043 */
044public class HSQLDBDialect extends StandardDialect
045{
046        private static final Set<Integer> failureCodes = new HashSet<Integer>(Arrays.asList(402, 407, 452, 460, 468));
047
048        /**
049         * {@inheritDoc}
050         * @see net.sf.hajdbc.dialect.StandardDialect#vendorPattern()
051         */
052        @Override
053        protected String vendorPattern()
054        {
055                return "hsqldb";
056        }
057
058        /**
059         * @see net.sf.hajdbc.dialect.StandardDialect#executeFunctionFormat()
060         */
061        @Override
062        protected String executeFunctionFormat()
063        {
064                return "CALL {0}";
065        }
066
067        /**
068         * {@inheritDoc}
069         * @see net.sf.hajdbc.dialect.StandardDialect#getSequenceSupport()
070         */
071        @Override
072        public SequenceSupport getSequenceSupport()
073        {
074                return this;
075        }
076
077        @Override
078        public List<String> getDefaultSchemas(DatabaseMetaData metaData)
079        {
080                return Collections.singletonList("PUBLIC");
081        }
082
083        @Override
084        public Collection<SequenceProperties> getSequences(DatabaseMetaData metaData, SequencePropertiesFactory factory) throws SQLException
085        {
086                Statement statement = metaData.getConnection().createStatement();
087                
088                try
089                {
090                        ResultSet resultSet = statement.executeQuery("SELECT SEQUENCE_SCHEMA, SEQUENCE_NAME, INCREMENT FROM INFORMATION_SCHEMA.SYSTEM_SEQUENCES");
091                        
092                        List<SequenceProperties> sequences = new LinkedList<SequenceProperties>();
093                        
094                        while (resultSet.next())
095                        {
096                                sequences.add(factory.createSequenceProperties(resultSet.getString(1), resultSet.getString(2), resultSet.getInt(3)));
097                        }
098                        
099                        return sequences;
100                }
101                finally
102                {
103                        Resources.close(statement);
104                }
105        }
106
107        /**
108         * Deferrability clause is not supported.
109         * @see net.sf.hajdbc.dialect.StandardDialect#createForeignKeyConstraintFormat()
110         */
111        @Override
112        protected String createForeignKeyConstraintFormat()
113        {
114                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}";
115        }
116
117        /**
118         * @see net.sf.hajdbc.dialect.StandardDialect#currentDatePattern()
119         */
120        @Override
121        protected String currentDatePattern()
122        {
123                return "(?<=\\W)CURRENT_DATE(?=\\W)|(?<=\\W)CURDATE\\s*\\(\\s*\\)";
124        }
125
126        /**
127         * @see net.sf.hajdbc.dialect.StandardDialect#currentTimePattern()
128         */
129        @Override
130        protected String currentTimePattern()
131        {
132                return "(?<=\\W)CURRENT_TIME(?=\\W)|(?<=\\W)CURTIME\\s*\\(\\s*\\)";
133        }
134
135        /**
136         * @see net.sf.hajdbc.dialect.StandardDialect#currentTimestampPattern()
137         */
138        @Override
139        protected String currentTimestampPattern()
140        {
141                return "(?<=\\W)CURRENT_TIMESTAMP(?=\\W)|(?<=\\W)NOW\\s*\\(\\s*\\)";
142        }
143
144        @Override
145        protected boolean indicatesFailure(int code)
146        {
147                return failureCodes.contains(code);
148        }
149}