From 9f9b4cde72716d8eb4a706b8c694409ad53ab22f Mon Sep 17 00:00:00 2001 From: mdb Date: Mon, 23 Oct 2006 23:12:55 +0000 Subject: [PATCH] Some refactoring of query generation; addition of "for update" support. From Zell. git-svn-id: https://samskivert.googlecode.com/svn/trunk@1961 6335cc39-0255-0410-8fd6-9bcaacd3b74c --- .../jdbc/depot/DepotMarshaller.java | 8 +-- .../jdbc/depot/DepotRepository.java | 8 +-- src/java/com/samskivert/jdbc/depot/Key.java | 1 + src/java/com/samskivert/jdbc/depot/Query.java | 22 ++++++-- .../jdbc/depot/clause/ForUpdateClause.java | 53 +++++++++++++++++++ .../jdbc/depot/clause/GroupByClause.java | 1 + .../jdbc/depot/clause/JoinClause.java | 1 + .../jdbc/depot/clause/LimitClause.java | 2 +- .../jdbc/depot/clause/OrderByClause.java | 1 + 9 files changed, 83 insertions(+), 14 deletions(-) create mode 100644 src/java/com/samskivert/jdbc/depot/clause/ForUpdateClause.java diff --git a/src/java/com/samskivert/jdbc/depot/DepotMarshaller.java b/src/java/com/samskivert/jdbc/depot/DepotMarshaller.java index 44cde835..9b610fe9 100644 --- a/src/java/com/samskivert/jdbc/depot/DepotMarshaller.java +++ b/src/java/com/samskivert/jdbc/depot/DepotMarshaller.java @@ -472,7 +472,7 @@ public class DepotMarshaller } update.append(field).append(" = ?"); } - update.append(" where "); key.appendClause(null, update); + key.appendClause(null, update); try { PreparedStatement pstmt = conn.prepareStatement(update.toString()); @@ -513,7 +513,7 @@ public class DepotMarshaller } update.append(field).append(" = ?"); } - update.append(" where "); key.appendClause(null, update); + key.appendClause(null, update); PreparedStatement pstmt = conn.prepareStatement(update.toString()); idx = 0; @@ -533,7 +533,7 @@ public class DepotMarshaller public PreparedStatement createDelete (Connection conn, Key key) throws SQLException { - StringBuilder query = new StringBuilder("delete from " + getTableName() + " where "); + StringBuilder query = new StringBuilder("delete from " + getTableName()); key.appendClause(null, query); PreparedStatement pstmt = conn.prepareStatement(query.toString()); key.bindArguments(pstmt, 1); @@ -557,7 +557,7 @@ public class DepotMarshaller update.append(modifiedFields[ii]).append(" = "); update.append(modifiedValues[ii]); } - update.append(" where "); key.appendClause(null, update); + key.appendClause(null, update); PreparedStatement pstmt = conn.prepareStatement(update.toString()); key.bindArguments(pstmt, 1); diff --git a/src/java/com/samskivert/jdbc/depot/DepotRepository.java b/src/java/com/samskivert/jdbc/depot/DepotRepository.java index b29b10e6..528210ff 100644 --- a/src/java/com/samskivert/jdbc/depot/DepotRepository.java +++ b/src/java/com/samskivert/jdbc/depot/DepotRepository.java @@ -58,20 +58,20 @@ public class DepotRepository /** * Loads the persistent object that matches the specified primary key. */ - protected T load (Class type, Comparable primaryKey) + protected T load (Class type, Comparable primaryKey, QueryClause... clauses) throws PersistenceException { - return load(type, _ctx.getMarshaller(type).makePrimaryKey(primaryKey)); + return load(type, _ctx.getMarshaller(type).makePrimaryKey(primaryKey), clauses); } /** * Loads the first persistent object that matches the supplied key. */ - protected T load (Class type, Key key) + protected T load (Class type, Key key, QueryClause... clauses) throws PersistenceException { final DepotMarshaller marsh = _ctx.getMarshaller(type); - return _ctx.invoke(new Query(_ctx, type, key) { + return _ctx.invoke(new Query(_ctx, type, key, clauses) { public T invoke (Connection conn) throws SQLException { PreparedStatement stmt = createQuery(conn); try { diff --git a/src/java/com/samskivert/jdbc/depot/Key.java b/src/java/com/samskivert/jdbc/depot/Key.java index 52b35a83..a5dda5fe 100644 --- a/src/java/com/samskivert/jdbc/depot/Key.java +++ b/src/java/com/samskivert/jdbc/depot/Key.java @@ -89,6 +89,7 @@ public class Key public void appendClause (Query query, StringBuilder builder) { + builder.append(" where "); for (int ii = 0; ii < columns.length; ii++) { if (ii > 0) { builder.append(" and "); diff --git a/src/java/com/samskivert/jdbc/depot/Query.java b/src/java/com/samskivert/jdbc/depot/Query.java index ec320465..c5bb3a3d 100644 --- a/src/java/com/samskivert/jdbc/depot/Query.java +++ b/src/java/com/samskivert/jdbc/depot/Query.java @@ -33,6 +33,7 @@ import java.util.Set; import com.samskivert.io.PersistenceException; import com.samskivert.jdbc.depot.clause.FieldOverrideClause; +import com.samskivert.jdbc.depot.clause.ForUpdateClause; import com.samskivert.jdbc.depot.clause.GroupByClause; import com.samskivert.jdbc.depot.clause.JoinClause; import com.samskivert.jdbc.depot.clause.LimitClause; @@ -130,25 +131,23 @@ public abstract class Query query.append(" from " + mainMarshaller.getTableName() + " as T "); for (JoinClause clause : _joinClauses) { - query.append(" inner join " ); clause.appendClause(this, query); } if (_key != null) { - query.append(" where "); _key.appendClause(this, query); } if (_groupBy != null) { - query.append(" group by "); _groupBy.appendClause(this, query); } if (_orderBy != null) { - query.append(" order by "); _orderBy.appendClause(this, query); } if (_limit != null) { - query.append(" limit "); _limit.appendClause(this, query); } + if (_forUpdate != null) { + _forUpdate.appendClause(this, query); + } PreparedStatement pstmt = conn.prepareStatement(query.toString()); int argIdx = 1; @@ -164,6 +163,9 @@ public abstract class Query if (_limit != null) { argIdx = _limit.bindArguments(pstmt, argIdx); } + if (_forUpdate != null) { + argIdx = _forUpdate.bindArguments(pstmt, argIdx); + } return pstmt; } @@ -215,6 +217,13 @@ public abstract class Query "Query can't contain multiple Limit clauses."); } _limit = (LimitClause) clause; + + } else if (clause instanceof ForUpdateClause) { + if (_forUpdate != null) { + throw new IllegalArgumentException( + "Query can't contain multiple For Update clauses."); + } + _forUpdate = (ForUpdateClause) clause; } } _classMap = new HashMap(); @@ -251,4 +260,7 @@ public abstract class Query /** The limit clause, if any. */ protected LimitClause _limit; + + /** The For Update clause, if any. */ + protected ForUpdateClause _forUpdate; } diff --git a/src/java/com/samskivert/jdbc/depot/clause/ForUpdateClause.java b/src/java/com/samskivert/jdbc/depot/clause/ForUpdateClause.java new file mode 100644 index 00000000..22f2dc85 --- /dev/null +++ b/src/java/com/samskivert/jdbc/depot/clause/ForUpdateClause.java @@ -0,0 +1,53 @@ +// +// $Id$ +// +// samskivert library - useful routines for java programs +// Copyright (C) 2006 Michael Bayne, Pär Winzell +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.samskivert.jdbc.depot.clause; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.Collection; + +import com.samskivert.jdbc.depot.Query; + +/** + * Represents a FOR UPDATE clause. + */ +public class ForUpdateClause + implements QueryClause +{ + // from QueryClause + public Collection getClassSet () + { + return null; + } + + // from QueryClause + public void appendClause (Query query, StringBuilder builder) + { + builder.append(" for update "); + } + + // from QueryClause + public int bindArguments (PreparedStatement pstmt, int argIdx) + throws SQLException + { + return argIdx; + } +} diff --git a/src/java/com/samskivert/jdbc/depot/clause/GroupByClause.java b/src/java/com/samskivert/jdbc/depot/clause/GroupByClause.java index 8b7c2efc..194f2789 100644 --- a/src/java/com/samskivert/jdbc/depot/clause/GroupByClause.java +++ b/src/java/com/samskivert/jdbc/depot/clause/GroupByClause.java @@ -48,6 +48,7 @@ public class GroupByClause // from QueryClause public void appendClause (Query query, StringBuilder builder) { + builder.append(" group by "); for (int ii = 0; ii < _values.length; ii++) { if (ii > 0) { builder.append(", "); diff --git a/src/java/com/samskivert/jdbc/depot/clause/JoinClause.java b/src/java/com/samskivert/jdbc/depot/clause/JoinClause.java index abd4f639..fd46d6a3 100644 --- a/src/java/com/samskivert/jdbc/depot/clause/JoinClause.java +++ b/src/java/com/samskivert/jdbc/depot/clause/JoinClause.java @@ -51,6 +51,7 @@ public class JoinClause // from QueryClause public void appendClause (Query query, StringBuilder builder) { + builder.append(" inner join " ); String jAbbrev = query.getTableAbbreviation(_joinClass); builder.append(query.getTableName(_joinClass) + " as " + jAbbrev + " on T." + _primaryColumn + " = " + jAbbrev + "." + _joinColumn); diff --git a/src/java/com/samskivert/jdbc/depot/clause/LimitClause.java b/src/java/com/samskivert/jdbc/depot/clause/LimitClause.java index 7fdd55c3..2faca3cb 100644 --- a/src/java/com/samskivert/jdbc/depot/clause/LimitClause.java +++ b/src/java/com/samskivert/jdbc/depot/clause/LimitClause.java @@ -48,7 +48,7 @@ public class LimitClause // from QueryClause public void appendClause (Query query, StringBuilder builder) { - builder.append("? offset ?"); + builder.append(" limit ? offset ? "); } // from QueryClause diff --git a/src/java/com/samskivert/jdbc/depot/clause/OrderByClause.java b/src/java/com/samskivert/jdbc/depot/clause/OrderByClause.java index e472a7bc..cec109ca 100644 --- a/src/java/com/samskivert/jdbc/depot/clause/OrderByClause.java +++ b/src/java/com/samskivert/jdbc/depot/clause/OrderByClause.java @@ -48,6 +48,7 @@ public class OrderByClause // from QueryClause public void appendClause (Query query, StringBuilder builder) { + builder.append(" order by "); for (int ii = 0; ii < _values.length; ii++) { if (ii > 0) { builder.append(", ");