/*
* Copyright 2005 Joe Walker
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.directwebremoting.datasync;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.directwebremoting.io.Item;
import org.directwebremoting.io.ItemUpdate;
import org.directwebremoting.io.MatchedItems;
import org.directwebremoting.io.SortCriterion;
import org.directwebremoting.io.StoreChangeListener;
import org.directwebremoting.io.StoreRegion;
/**
* This file is not supported in any way, and does not function correctly.
* It might become part of DWR proper at some later date
* @author Joe Walker [jwalker at sitepen dot com]
*/
class SqlStoreProvider<T> extends AbstractStoreProvider<T>
{
/**
*
*/
private SqlStoreProvider(Class<T> type)
{
super(type);
}
/**
* The primary key must be the first column
*/
private static final String BASE_SQL = "SELECT col1, col2 FROM table";
/* (non-Javadoc)
* @see org.directwebremoting.datasync.StoreProvider#view(org.directwebremoting.io.StoreRegion)
*/
public MatchedItems view(StoreRegion region)
{
// Turn the query into a WHERE clause and an array of parameters
List<String> params = new ArrayList<String>();
StringBuilder where = new StringBuilder();
for (Map.Entry<String, String> entry : region.getQuery().entrySet())
{
if (where.length() == 0)
{
where.append(" WHERE ");
}
else
{
where.append(" AND ");
}
String key = entry.getKey();
where.append(key);
where.append(" = :");
where.append(key);
params.add(entry.getValue());
}
// Create an ORDER BY clause
StringBuilder orderBy = new StringBuilder();
for (SortCriterion element : region.getSort())
{
if (where.length() == 0)
{
where.append(" ORDER BY ");
}
else
{
where.append(", ");
}
where.append(element.getAttribute());
where.append(element.isAscending() ? "ASC" : "DESC");
}
// Create a LIMIT x OFFSET y clause
int start = region.getStart();
int count = region.getCount();
String paging;
if (start == 0)
{
if (count == -1)
{
// No paging
paging = "";
}
else
{
// only as far as 'count'
paging = " LIMIT " + count;
}
}
else
{
if (count == -1)
{
throw new UnsupportedOperationException("Can't select a start point without selecting a count");
}
// only as far as 'count'
paging = " LIMIT " + count + " OFFSET " + start;
}
String sql = BASE_SQL + where + orderBy + paging;
Connection con = null;
PreparedStatement stmt = null;
ResultSet rs = null;
List<Item> matchedValues = new ArrayList<Item>();
try
{
con = dataSource.getConnection();
stmt = con.prepareStatement(sql);
int index = 1;
for (String element : params)
{
stmt.setString(index++, element);
}
rs = stmt.executeQuery();
ResultSetMetaData metaData = rs.getMetaData();
int columnCount = metaData.getColumnCount();
// We're going to ignore the zeroth index to be like jdbc
String[] columnNames = new String[columnCount + 1];
for (int col = 1; col <= columnCount; col++)
{
columnNames[col] = metaData.getColumnName(col);
}
Map<String, String> data = new HashMap<String, String>();
while (rs.next())
{
String itemId = rs.getString(1);
for (int col = 2; col <= columnCount; col++)
{
data.put(columnNames[col], rs.getString(col));
}
matchedValues.add(new Item(itemId, data));
}
}
catch (SQLException ex)
{
log.warn("SQL Failure", ex);
}
finally
{
if (con != null)
{
try
{
con.close();
}
catch (SQLException ex2)
{
log.warn("Error closing connection", ex2);
}
}
if (stmt != null)
{
try
{
stmt.close();
}
catch (SQLException ex2)
{
log.warn("Error closing statement", ex2);
}
}
if (rs != null)
{
try
{
rs.close();
}
catch (SQLException ex2)
{
log.warn("Error closing resultset", ex2);
}
}
}
MatchedItems reply = new MatchedItems(matchedValues, -1);
return reply;
}
protected DataSource dataSource;
public void setDataSource(DataSource dataSource)
{
this.dataSource = dataSource;
}
/* (non-Javadoc)
* @see org.directwebremoting.datasync.StoreProvider#put(java.lang.String, java.lang.Object)
*/
public void put(String itemId, T value)
{
throw new UnsupportedOperationException("SqlStoreProvider is read only");
}
/* (non-Javadoc)
* @see org.directwebremoting.datasync.AbstractStoreProvider#getObject(java.lang.String)
*/
@Override
protected T getObject(String itemId)
{
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see org.directwebremoting.datasync.StoreProvider#unsubscribe(org.directwebremoting.io.StoreChangeListener)
*/
public void unsubscribe(StoreChangeListener<T> listener)
{
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see org.directwebremoting.datasync.StoreProvider#update(java.util.List)
*/
public void update(List<ItemUpdate> changes)
{
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see org.directwebremoting.datasync.StoreProvider#viewItem(java.lang.String, org.directwebremoting.io.StoreChangeListener)
*/
public Item viewItem(String itemId, StoreChangeListener<T> listener)
{
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see org.directwebremoting.datasync.StoreProvider#viewRegion(org.directwebremoting.io.StoreRegion)
*/
public MatchedItems viewRegion(StoreRegion region)
{
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see org.directwebremoting.datasync.StoreProvider#viewRegion(org.directwebremoting.io.StoreRegion, org.directwebremoting.io.StoreChangeListener)
*/
public MatchedItems viewRegion(StoreRegion region, StoreChangeListener<T> listener)
{
// TODO Auto-generated method stub
return null;
}
/**
* The log stream
*/
private static final Log log = LogFactory.getLog(SqlStoreProvider.class);
}