001/* 002 * Copyright 2006-2012 the original author or authors. 003 * 004 * Licensed under the Apache 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 * https://www.apache.org/licenses/LICENSE-2.0 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 017package org.springframework.batch.item.database.support; 018 019import javax.sql.DataSource; 020 021import org.springframework.batch.item.database.PagingQueryProvider; 022import org.springframework.dao.InvalidDataAccessResourceUsageException; 023import org.springframework.jdbc.support.JdbcUtils; 024 025/** 026 * Derby implementation of a {@link PagingQueryProvider} using standard SQL:2003 windowing functions. 027 * These features are supported starting with Apache Derby version 10.4.1.3. 028 * 029 * As the OVER() function does not support the ORDER BY clause a sub query is instead used to order the results 030 * before the ROW_NUM restriction is applied 031 * 032 * @author Thomas Risberg 033 * @author David Thexton 034 * @author Michael Minella 035 * @since 2.0 036 */ 037public class DerbyPagingQueryProvider extends SqlWindowingPagingQueryProvider { 038 039 private static final String MINIMAL_DERBY_VERSION = "10.4.1.3"; 040 041 @Override 042 public void init(DataSource dataSource) throws Exception { 043 super.init(dataSource); 044 String version = JdbcUtils.extractDatabaseMetaData(dataSource, "getDatabaseProductVersion").toString(); 045 if (!isDerbyVersionSupported(version)) { 046 throw new InvalidDataAccessResourceUsageException("Apache Derby version " + version + " is not supported by this class, Only version " + MINIMAL_DERBY_VERSION + " or later is supported"); 047 } 048 } 049 050 // derby version numbering is M.m.f.p [ {alpha|beta} ] see https://db.apache.org/derby/papers/versionupgrade.html#Basic+Numbering+Scheme 051 private boolean isDerbyVersionSupported(String version) { 052 String[] minimalVersionParts = MINIMAL_DERBY_VERSION.split("\\."); 053 String[] versionParts = version.split("[\\. ]"); 054 for (int i = 0; i < minimalVersionParts.length; i++) { 055 int minimalVersionPart = Integer.valueOf(minimalVersionParts[i]); 056 int versionPart = Integer.valueOf(versionParts[i]); 057 if (versionPart < minimalVersionPart) { 058 return false; 059 } else if (versionPart > minimalVersionPart) { 060 return true; 061 } 062 } 063 return true; 064 } 065 066 @Override 067 protected String getOrderedQueryAlias() { 068 return "TMP_ORDERED"; 069 } 070 071 @Override 072 protected String getOverClause() { 073 return ""; 074 } 075 076 @Override 077 protected String getOverSubstituteClauseStart() { 078 return " FROM (SELECT " + getSelectClause(); 079 } 080 081 @Override 082 protected String getOverSubstituteClauseEnd() { 083 return " ) AS " + getOrderedQueryAlias(); 084 } 085 086}