com.vaadin.v7.data.util.sqlcontainer.query.FreeformQuery Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vaadin-compatibility-server Show documentation
Show all versions of vaadin-compatibility-server Show documentation
Vaadin 7 compatibility package for Vaadin 8
/*
* Copyright (C) 2000-2024 Vaadin Ltd
*
* This program is available under Vaadin Commercial License and Service Terms.
*
* See for the full
* license.
*/
package com.vaadin.v7.data.util.sqlcontainer.query;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import com.vaadin.v7.data.Container.Filter;
import com.vaadin.v7.data.util.sqlcontainer.RowItem;
import com.vaadin.v7.data.util.sqlcontainer.SQLContainer;
import com.vaadin.v7.data.util.sqlcontainer.connection.JDBCConnectionPool;
import com.vaadin.v7.data.util.sqlcontainer.query.generator.StatementHelper;
import com.vaadin.v7.data.util.sqlcontainer.query.generator.filter.QueryBuilder;
/**
* @deprecated As of 8.0, no replacement available.
*/
@SuppressWarnings("serial")
@Deprecated
public class FreeformQuery extends AbstractTransactionalQuery
implements QueryDelegate {
FreeformQueryDelegate delegate = null;
private String queryString;
private List primaryKeyColumns;
/**
* Prevent no-parameters instantiation of FreeformQuery
*/
@SuppressWarnings("unused")
private FreeformQuery() {
}
/**
* Creates a new freeform query delegate to be used with the
* {@link SQLContainer}.
*
* @param queryString
* The actual query to perform.
* @param primaryKeyColumns
* The primary key columns. Read-only mode is forced if this
* parameter is null or empty.
* @param connectionPool
* the JDBCConnectionPool to use to open connections to the SQL
* database.
* @deprecated As of 6.7, @see
* {@link FreeformQuery#FreeformQuery(String, JDBCConnectionPool, String...)}
*/
@Deprecated
public FreeformQuery(String queryString, List primaryKeyColumns,
JDBCConnectionPool connectionPool) {
super(connectionPool);
if (primaryKeyColumns == null) {
primaryKeyColumns = new ArrayList();
}
if (primaryKeyColumns.contains("")) {
throw new IllegalArgumentException(
"The primary key columns contain an empty string!");
} else if (queryString == null || "".equals(queryString)) {
throw new IllegalArgumentException(
"The query string may not be empty or null!");
} else if (connectionPool == null) {
throw new IllegalArgumentException(
"The connectionPool may not be null!");
}
this.queryString = queryString;
this.primaryKeyColumns = Collections
.unmodifiableList(primaryKeyColumns);
}
/**
* Creates a new freeform query delegate to be used with the
* {@link SQLContainer}.
*
* @param queryString
* The actual query to perform.
* @param connectionPool
* the JDBCConnectionPool to use to open connections to the SQL
* database.
* @param primaryKeyColumns
* The primary key columns. Read-only mode is forced if none are
* provided. (optional)
*/
public FreeformQuery(String queryString, JDBCConnectionPool connectionPool,
String... primaryKeyColumns) {
this(queryString, Arrays.asList(primaryKeyColumns), connectionPool);
}
/**
* This implementation of getCount() actually fetches all records from the
* database, which might be a performance issue. Override this method with a
* SELECT COUNT(*) ... query if this is too slow for your needs.
*
* {@inheritDoc}
*/
@Override
public int getCount() throws SQLException {
// First try the delegate
int count = countByDelegate();
if (count < 0) {
// Couldn't use the delegate, use the bad way.
Statement statement = null;
ResultSet rs = null;
Connection conn = getConnection();
try {
statement = conn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
rs = statement.executeQuery(queryString);
if (rs.last()) {
count = rs.getRow();
} else {
count = 0;
}
} finally {
releaseConnection(conn, statement, rs);
}
}
return count;
}
@SuppressWarnings("deprecation")
private int countByDelegate() throws SQLException {
int count = -1;
if (delegate == null) {
return count;
}
/* First try using prepared statement */
if (delegate instanceof FreeformStatementDelegate) {
try {
StatementHelper sh = ((FreeformStatementDelegate) delegate)
.getCountStatement();
PreparedStatement pstmt = null;
ResultSet rs = null;
Connection c = getConnection();
try {
pstmt = c.prepareStatement(sh.getQueryString());
sh.setParameterValuesToStatement(pstmt);
rs = pstmt.executeQuery();
if (rs.next()) {
count = rs.getInt(1);
} else {
// The result can be empty when using group by and there
// are no matches (#18043)
count = 0;
}
} finally {
releaseConnection(c, pstmt, rs);
}
return count;
} catch (UnsupportedOperationException e) {
// Count statement generation not supported
}
}
/* Try using regular statement */
try {
String countQuery = delegate.getCountQuery();
if (countQuery != null) {
Statement statement = null;
ResultSet rs = null;
Connection conn = getConnection();
try {
statement = conn.createStatement();
rs = statement.executeQuery(countQuery);
if (rs.next()) {
count = rs.getInt(1);
} else {
// The result can be empty when using group by and there
// are no matches (#18043)
count = 0;
}
return count;
} finally {
releaseConnection(conn, statement, rs);
}
}
} catch (UnsupportedOperationException e) {
// Count query generation not supported
}
return count;
}
/**
* Fetches the results for the query. This implementation always fetches the
* entire record set, ignoring the offset and page length parameters. In
* order to support lazy loading of records, you must supply a
* FreeformQueryDelegate that implements the
* FreeformQueryDelegate.getQueryString(int,int) method.
*
* @throws SQLException
*
* @see FreeformQueryDelegate#getQueryString(int, int)
*/
@Override
@SuppressWarnings({ "deprecation", "finally" })
public ResultSet getResults(int offset, int pagelength)
throws SQLException {
ensureTransaction();
String query = queryString;
if (delegate != null) {
/* First try using prepared statement */
if (delegate instanceof FreeformStatementDelegate) {
try {
StatementHelper sh = ((FreeformStatementDelegate) delegate)
.getQueryStatement(offset, pagelength);
PreparedStatement pstmt = getConnection()
.prepareStatement(sh.getQueryString());
sh.setParameterValuesToStatement(pstmt);
return pstmt.executeQuery();
} catch (UnsupportedOperationException e) {
// Statement generation not supported, continue...
}
}
try {
query = delegate.getQueryString(offset, pagelength);
} catch (UnsupportedOperationException e) {
// This is fine, we'll just use the default queryString.
}
}
Statement statement = getConnection().createStatement();
ResultSet rs;
try {
rs = statement.executeQuery(query);
} catch (SQLException e) {
try {
statement.close();
} finally {
// throw the original exception even if closing the statement
// fails
throw e;
}
}
return rs;
}
@Override
@SuppressWarnings("deprecation")
public boolean implementationRespectsPagingLimits() {
if (delegate == null) {
return false;
}
/* First try using prepared statement */
if (delegate instanceof FreeformStatementDelegate) {
try {
StatementHelper sh = ((FreeformStatementDelegate) delegate)
.getCountStatement();
if (sh != null && sh.getQueryString() != null
&& !sh.getQueryString().isEmpty()) {
return true;
}
} catch (UnsupportedOperationException e) {
// Statement generation not supported, continue...
}
}
try {
String queryString = delegate.getQueryString(0, 50);
return queryString != null && !queryString.isEmpty();
} catch (UnsupportedOperationException e) {
return false;
}
}
/*
* (non-Javadoc)
*
* @see
* com.vaadin.data.util.sqlcontainer.query.QueryDelegate#setFilters(java
* .util.List)
*/
@Override
public void setFilters(List filters)
throws UnsupportedOperationException {
if (delegate != null) {
delegate.setFilters(filters);
} else if (filters != null) {
throw new UnsupportedOperationException(
"FreeFormQueryDelegate not set!");
}
}
/*
* (non-Javadoc)
*
* @see
* com.vaadin.data.util.sqlcontainer.query.QueryDelegate#setOrderBy(java
* .util.List)
*/
@Override
public void setOrderBy(List orderBys)
throws UnsupportedOperationException {
if (delegate != null) {
delegate.setOrderBy(orderBys);
} else if (orderBys != null) {
throw new UnsupportedOperationException(
"FreeFormQueryDelegate not set!");
}
}
/*
* (non-Javadoc)
*
* @see
* com.vaadin.data.util.sqlcontainer.query.QueryDelegate#storeRow(com.vaadin
* .data.util.sqlcontainer.RowItem)
*/
@Override
public int storeRow(RowItem row) throws SQLException {
if (!isInTransaction()) {
throw new IllegalStateException("No transaction is active!");
} else if (primaryKeyColumns.isEmpty()) {
throw new UnsupportedOperationException(
"Cannot store items fetched with a read-only freeform query!");
}
if (delegate != null) {
return delegate.storeRow(getConnection(), row);
} else {
throw new UnsupportedOperationException(
"FreeFormQueryDelegate not set!");
}
}
/*
* (non-Javadoc)
*
* @see com.vaadin.data.util.sqlcontainer.query.QueryDelegate#removeRow(com.
* vaadin .data.util.sqlcontainer.RowItem)
*/
@Override
public boolean removeRow(RowItem row) throws SQLException {
if (!isInTransaction()) {
throw new IllegalStateException("No transaction is active!");
} else if (primaryKeyColumns.isEmpty()) {
throw new UnsupportedOperationException(
"Cannot remove items fetched with a read-only freeform query!");
}
if (delegate != null) {
return delegate.removeRow(getConnection(), row);
} else {
throw new UnsupportedOperationException(
"FreeFormQueryDelegate not set!");
}
}
@Override
public synchronized void beginTransaction()
throws UnsupportedOperationException, SQLException {
super.beginTransaction();
}
@Override
public synchronized void commit()
throws UnsupportedOperationException, SQLException {
super.commit();
}
@Override
public synchronized void rollback()
throws UnsupportedOperationException, SQLException {
super.rollback();
}
/*
* (non-Javadoc)
*
* @see com.vaadin.data.util.sqlcontainer.query.QueryDelegate#
* getPrimaryKeyColumns ()
*/
@Override
public List getPrimaryKeyColumns() {
return primaryKeyColumns;
}
public String getQueryString() {
return queryString;
}
public FreeformQueryDelegate getDelegate() {
return delegate;
}
public void setDelegate(FreeformQueryDelegate delegate) {
this.delegate = delegate;
}
/**
* This implementation of the containsRowWithKey method rewrites existing
* WHERE clauses in the query string. The logic is, however, not very
* complex and some times can do the Wrong ThingTM. For the
* situations where this logic is not enough, you can implement the
* getContainsRowQueryString method in FreeformQueryDelegate and this will
* be used instead of the logic.
*
* @see FreeformQueryDelegate#getContainsRowQueryString(Object...)
*
*/
@Override
@SuppressWarnings("deprecation")
public boolean containsRowWithKey(Object... keys) throws SQLException {
String query = null;
boolean contains = false;
if (delegate != null) {
if (delegate instanceof FreeformStatementDelegate) {
try {
StatementHelper sh = ((FreeformStatementDelegate) delegate)
.getContainsRowQueryStatement(keys);
PreparedStatement pstmt = null;
ResultSet rs = null;
Connection c = getConnection();
try {
pstmt = c.prepareStatement(sh.getQueryString());
sh.setParameterValuesToStatement(pstmt);
rs = pstmt.executeQuery();
contains = rs.next();
return contains;
} finally {
releaseConnection(c, pstmt, rs);
}
} catch (UnsupportedOperationException e) {
// Statement generation not supported, continue...
}
}
try {
query = delegate.getContainsRowQueryString(keys);
} catch (UnsupportedOperationException e) {
query = modifyWhereClause(keys);
}
} else {
query = modifyWhereClause(keys);
}
Statement statement = null;
ResultSet rs = null;
Connection conn = getConnection();
try {
statement = conn.createStatement();
rs = statement.executeQuery(query);
contains = rs.next();
} finally {
releaseConnection(conn, statement, rs);
}
return contains;
}
private String modifyWhereClause(Object... keys) {
// Build the where rules for the provided keys
StringBuilder where = new StringBuilder();
for (int ix = 0; ix < primaryKeyColumns.size(); ix++) {
where.append(QueryBuilder.quote(primaryKeyColumns.get(ix)));
if (keys[ix] == null) {
where.append(" IS NULL");
} else {
where.append(" = '").append(keys[ix]).append('\'');
}
if (ix < primaryKeyColumns.size() - 1) {
where.append(" AND ");
}
}
// Is there already a WHERE clause in the query string?
int index = queryString.toLowerCase(Locale.ROOT).indexOf("where ");
if (index > -1) {
// Rewrite the where clause
return queryString.substring(0, index) + "WHERE " + where + " AND "
+ queryString.substring(index + 6);
}
// Append a where clause
return queryString + " WHERE " + where;
}
private void writeObject(java.io.ObjectOutputStream out)
throws IOException {
try {
rollback();
} catch (SQLException ignored) {
}
out.defaultWriteObject();
}
}