mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-04 20:29:27 +01:00
propagating transaction isolation fix for merovingian2
This commit is contained in:
parent
a86f49c106
commit
d54f6d536a
@ -383,7 +383,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
|
||||
}
|
||||
}
|
||||
|
||||
s_logger.warn("No handling of agent control command: " + cmd.toString() + " sent from " + attache.getId());
|
||||
s_logger.warn("No handling of agent control command: " + cmd + " sent from " + attache.getId());
|
||||
return new AgentControlAnswer(cmd);
|
||||
}
|
||||
|
||||
@ -601,7 +601,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
|
||||
Status currentState = host.getStatus();
|
||||
Status nextState = currentState.getNextStatus(Status.Event.Remove);
|
||||
if (nextState == null) {
|
||||
s_logger.debug("There is no transition from state " + currentState.toString() + " to state " + Status.Event.Remove.toString());
|
||||
s_logger.debug("There is no transition from state " + currentState + " to state " + Status.Event.Remove);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -981,7 +981,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
|
||||
|
||||
long hostId = attache.getId();
|
||||
|
||||
s_logger.info("Host " + hostId + " is disconnecting with event " + event.toString());
|
||||
s_logger.info("Host " + hostId + " is disconnecting with event " + event);
|
||||
|
||||
HostVO host = _hostDao.findById(hostId);
|
||||
if (host == null) {
|
||||
@ -993,7 +993,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
|
||||
final Status currentState = host.getStatus();
|
||||
if (currentState == Status.Down || currentState == Status.Alert || currentState == Status.Removed) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Host " + hostId + " is already " + currentState.toString());
|
||||
s_logger.debug("Host " + hostId + " is already " + currentState);
|
||||
}
|
||||
if (currentState != Status.PrepareForMaintenance) {
|
||||
removeAgent(attache, currentState);
|
||||
@ -1006,21 +1006,21 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
|
||||
return false;
|
||||
}
|
||||
|
||||
s_logger.debug("There is no transition from state " + currentState.toString() + " and event " + event.toString());
|
||||
s_logger.debug("There is no transition from state " + currentState + " and event " + event);
|
||||
assert false : "How did we get here. Look at the FSM";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("The next state is " + nextState.toString() + ", current state is " + currentState);
|
||||
s_logger.debug("The next state is " + nextState + ", current state is " + currentState);
|
||||
}
|
||||
|
||||
// Now we go and correctly diagnose what the actual situation is
|
||||
if (nextState == Status.Alert && investigate) {
|
||||
s_logger.info("Investigating why host " + hostId + " has disconnected with event " + event.toString());
|
||||
s_logger.info("Investigating why host " + hostId + " has disconnected with event " + event);
|
||||
|
||||
final Status determinedState = investigate(attache);
|
||||
s_logger.info("The state determined is " + (determinedState != null ? determinedState.toString() : "undeterminable"));
|
||||
s_logger.info("The state determined is " + determinedState);
|
||||
|
||||
if (determinedState == null || determinedState == Status.Down) {
|
||||
s_logger.error("Host is down: " + host.getId() + "-" + host.getName() + ". Starting HA on the VMs");
|
||||
@ -1446,7 +1446,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
|
||||
try {
|
||||
Host h = _hostDao.findById(hostId);
|
||||
if (h == null || h.getRemoved() != null) {
|
||||
s_logger.debug("Host with id " + hostId.toString() + " doesn't exist");
|
||||
s_logger.debug("Host with id " + hostId + " doesn't exist");
|
||||
return null;
|
||||
}
|
||||
Status status = h.getStatus();
|
||||
@ -1460,7 +1460,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
|
||||
}
|
||||
|
||||
if (s_logger.isDebugEnabled() && answer.getDetails() != null) {
|
||||
s_logger.debug("Details from executing " + cmd.getClass().toString() + ": " + answer.getDetails());
|
||||
s_logger.debug("Details from executing " + cmd.getClass() + ": " + answer.getDetails());
|
||||
}
|
||||
|
||||
return answer;
|
||||
@ -1530,7 +1530,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
|
||||
List<VMInstanceVO> vms = _haMgr.findTakenMigrationWork();
|
||||
for (VMInstanceVO vm : vms) {
|
||||
if (vm.getHostId() != null && vm.getHostId() == hostId) {
|
||||
s_logger.info("Unable to cancel migration because the vm is being migrated: " + vm.toString());
|
||||
s_logger.info("Unable to cancel migration because the vm is being migrated: " + vm);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1595,8 +1595,8 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
|
||||
}
|
||||
state = host.getStatus();
|
||||
if (state == Status.Disconnected || state == Status.Updating) {
|
||||
s_logger.debug("Unable to put host " + hostId + " in matinenance mode because it is currently in " + state.toString());
|
||||
throw new AgentUnavailableException("Agent is in " + state.toString() + " state. Please wait for it to become Alert state try again.", hostId);
|
||||
s_logger.debug("Unable to put host " + hostId + " in matinenance mode because it is currently in " + state);
|
||||
throw new AgentUnavailableException("Agent is in " + state + " state. Please wait for it to become Alert state try again.", hostId);
|
||||
}
|
||||
} while (!_hostDao.updateStatus(host, Event.MaintenanceRequested, _nodeId));
|
||||
|
||||
@ -1865,12 +1865,12 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
|
||||
server = _hostDao.persist(server);
|
||||
id = server.getId();
|
||||
|
||||
s_logger.info("New " + server.getType().toString() + " host connected w/ guid " + startup.getGuid() + " and id is " + id);
|
||||
s_logger.info("New " + server.getType() + " host connected w/ guid " + startup.getGuid() + " and id is " + id);
|
||||
} else {
|
||||
if (!_hostDao.connect(server, _nodeId)) {
|
||||
throw new CloudRuntimeException("Agent cannot connect because the current state is " + server.getStatus().toString());
|
||||
throw new CloudRuntimeException("Agent cannot connect because the current state is " + server.getStatus());
|
||||
}
|
||||
s_logger.info("Old " + server.getType().toString() + " host reconnected w/ id =" + id);
|
||||
s_logger.info("Old " + server.getType() + " host reconnected w/ id =" + id);
|
||||
}
|
||||
|
||||
return server;
|
||||
@ -2201,7 +2201,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
|
||||
if (attache == null) {
|
||||
request.logD("Processing the first command ");
|
||||
if (!(cmd instanceof StartupCommand)) {
|
||||
s_logger.warn("Throwing away a request because it came through as the first command on a connect: " + request.toString());
|
||||
s_logger.warn("Throwing away a request because it came through as the first command on a connect: " + request);
|
||||
return;
|
||||
}
|
||||
StartupCommand startup = (StartupCommand) cmd;
|
||||
@ -2228,28 +2228,28 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
|
||||
attache = handleConnect(link, startups);
|
||||
} catch (final IllegalArgumentException e) {
|
||||
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, 0, new Long(0), "Agent from " + startup.getPrivateIpAddress() + " is unable to connect due to " + e.getMessage(), "Agent from "
|
||||
+ startup.getPrivateIpAddress() + " is unable to connect with " + request.toString() + " because of " + e.getMessage());
|
||||
s_logger.warn("Unable to create attache for agent: " + request.toString(), e);
|
||||
+ startup.getPrivateIpAddress() + " is unable to connect with " + request + " because of " + e.getMessage());
|
||||
s_logger.warn("Unable to create attache for agent: " + request, e);
|
||||
response = new Response(request, new StartupAnswer((StartupCommand) cmd, e.getMessage()), _nodeId, -1);
|
||||
} catch (ConnectionException e) {
|
||||
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, 0, new Long(0), "Agent from " + startup.getPrivateIpAddress() + " is unable to connect due to " + e.getMessage(), "Agent from "
|
||||
+ startup.getPrivateIpAddress() + " is unable to connect with " + request.toString() + " because of " + e.getMessage());
|
||||
s_logger.warn("Unable to create attache for agent: " + request.toString(), e);
|
||||
+ startup.getPrivateIpAddress() + " is unable to connect with " + request + " because of " + e.getMessage());
|
||||
s_logger.warn("Unable to create attache for agent: " + request, e);
|
||||
response = new Response(request, new StartupAnswer((StartupCommand) cmd, e.getMessage()), _nodeId, -1);
|
||||
} catch (final CloudRuntimeException e) {
|
||||
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, 0, new Long(0), "Agent from " + startup.getPrivateIpAddress() + " is unable to connect due to " + e.getMessage(), "Agent from "
|
||||
+ startup.getPrivateIpAddress() + " is unable to connect with " + request.toString() + " because of " + e.getMessage());
|
||||
s_logger.warn("Unable to create attache for agent: " + request.toString(), e);
|
||||
+ startup.getPrivateIpAddress() + " is unable to connect with " + request + " because of " + e.getMessage());
|
||||
s_logger.warn("Unable to create attache for agent: " + request, e);
|
||||
}
|
||||
if (attache == null) {
|
||||
if (response == null) {
|
||||
s_logger.warn("Unable to create attache for agent: " + request.toString());
|
||||
s_logger.warn("Unable to create attache for agent: " + request);
|
||||
response = new Response(request, new StartupAnswer((StartupCommand) request.getCommand(), "Unable to register this agent"), _nodeId, -1);
|
||||
}
|
||||
try {
|
||||
link.send(response.toBytes(), true);
|
||||
} catch (final ClosedChannelException e) {
|
||||
s_logger.warn("Response was not sent: " + response.toString());
|
||||
s_logger.warn("Response was not sent: " + response);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -2261,18 +2261,18 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
|
||||
if (cmd instanceof PingRoutingCommand) {
|
||||
final PingRoutingCommand ping = (PingRoutingCommand) cmd;
|
||||
if (ping.getNewStates().size() > 0) {
|
||||
s_logger.debug("SeqA " + hostId + "-" + request.getSequence() + ": Processing " + request.toString());
|
||||
s_logger.debug("SeqA " + hostId + "-" + request.getSequence() + ": Processing " + request);
|
||||
} else {
|
||||
logD = false;
|
||||
s_logger.debug("Ping from " + hostId);
|
||||
s_logger.trace("SeqA " + hostId + "-" + request.getSequence() + ": Processing " + request.toString());
|
||||
s_logger.trace("SeqA " + hostId + "-" + request.getSequence() + ": Processing " + request);
|
||||
}
|
||||
} else if (cmd instanceof PingCommand) {
|
||||
logD = false;
|
||||
s_logger.debug("Ping from " + hostId);
|
||||
s_logger.trace("SeqA " + attache.getId() + "-" + request.getSequence() + ": Processing " + request.toString());
|
||||
s_logger.trace("SeqA " + attache.getId() + "-" + request.getSequence() + ": Processing " + request);
|
||||
} else {
|
||||
s_logger.debug("SeqA " + attache.getId() + "-" + request.getSequence() + ": Processing " + request.toString());
|
||||
s_logger.debug("SeqA " + attache.getId() + "-" + request.getSequence() + ": Processing " + request);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2351,26 +2351,26 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
|
||||
response = new Response(request, answers, _nodeId, attache.getId());
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
if (logD) {
|
||||
s_logger.debug("SeqA " + attache.getId() + "-" + response.getSequence() + ": Sending " + response.toString());
|
||||
s_logger.debug("SeqA " + attache.getId() + "-" + response.getSequence() + ": Sending " + response);
|
||||
} else {
|
||||
s_logger.trace("SeqA " + attache.getId() + "-" + response.getSequence() + ": Sending " + response.toString());
|
||||
s_logger.trace("SeqA " + attache.getId() + "-" + response.getSequence() + ": Sending " + response);
|
||||
}
|
||||
}
|
||||
try {
|
||||
link.send(response.toBytes());
|
||||
} catch (final ClosedChannelException e) {
|
||||
s_logger.warn("Unable to send response because connection is closed: " + response.toString());
|
||||
s_logger.warn("Unable to send response because connection is closed: " + response);
|
||||
}
|
||||
}
|
||||
|
||||
protected void processResponse(final Link link, final Response response) {
|
||||
final AgentAttache attache = (AgentAttache) link.attachment();
|
||||
if (attache == null) {
|
||||
s_logger.warn("Unable to process: " + response.toString());
|
||||
s_logger.warn("Unable to process: " + response);
|
||||
}
|
||||
|
||||
if (!attache.processAnswers(response.getSequence(), response)) {
|
||||
s_logger.info("Host " + attache.getId() + " - Seq " + response.getSequence() + ": Response is not processed: " + response.toString());
|
||||
s_logger.info("Host " + attache.getId() + " - Seq " + response.getSequence() + ": Response is not processed: " + response);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
101
utils/src/com/cloud/utils/db/Condition.java
Normal file
101
utils/src/com/cloud/utils/db/Condition.java
Normal file
@ -0,0 +1,101 @@
|
||||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.utils.db;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
|
||||
public class Condition<T, K> {
|
||||
Where<T, K> _where;
|
||||
Attribute _attr;
|
||||
String _as;
|
||||
SearchCriteria.Op _op;
|
||||
String _paramName;
|
||||
|
||||
protected Condition(Where<T, K> where, Attribute attr, String as) {
|
||||
assert (where != null) : "What am I going to return to the user when Where is null?";
|
||||
assert (attr != null) : "What's the point of giving me a null attribute?";
|
||||
_where = where;
|
||||
_attr = attr;
|
||||
_as = as;
|
||||
}
|
||||
|
||||
protected NextWhere<T, K> set(Op op, String paramName) {
|
||||
_op = op;
|
||||
_paramName = paramName;
|
||||
Where<T, K> where = _where;
|
||||
_where = null;
|
||||
return where;
|
||||
}
|
||||
|
||||
public NextWhere<T, K> eq(String paramName) {
|
||||
return set(Op.EQ, paramName);
|
||||
}
|
||||
|
||||
public NextWhere<T, K> lt(String paramName) {
|
||||
return set(Op.LT, paramName);
|
||||
}
|
||||
|
||||
public NextWhere<T, K> lteq(String paramName) {
|
||||
return set(Op.LTEQ, paramName);
|
||||
}
|
||||
|
||||
public NextWhere<T, K> gt(String paramName) {
|
||||
return set(Op.GT, paramName);
|
||||
}
|
||||
|
||||
public NextWhere<T, K> isNull() {
|
||||
return set(Op.NULL, null);
|
||||
}
|
||||
|
||||
public NextWhere<T, K> isNotNull() {
|
||||
return set(Op.NNULL, null);
|
||||
}
|
||||
|
||||
public NextWhere<T, K> in(String paramName) {
|
||||
_op = Op.IN;
|
||||
_paramName = paramName;
|
||||
return _where;
|
||||
}
|
||||
|
||||
protected String getParamName() {
|
||||
assert (_paramName instanceof String) : "Well, how can we get back a parameter name if it was not assigned one?";
|
||||
return _paramName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return _paramName.equals(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return _paramName.hashCode();
|
||||
}
|
||||
|
||||
public void toSql(StringBuilder builder, HashMap<String, Object[]> values) {
|
||||
if (_as != null) {
|
||||
builder.append(_as);
|
||||
} else {
|
||||
builder.append(_attr.table);
|
||||
}
|
||||
builder.append(".").append(_attr.columnName);
|
||||
}
|
||||
|
||||
}
|
||||
30
utils/src/com/cloud/utils/db/FirstWhere.java
Normal file
30
utils/src/com/cloud/utils/db/FirstWhere.java
Normal file
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.utils.db;
|
||||
|
||||
public interface FirstWhere<T, K> {
|
||||
Condition<T, K> field(Object field);
|
||||
|
||||
Condition<T, K> field(Object field, String as);
|
||||
|
||||
NextWhere<T, K> text(String text, String... paramNames);
|
||||
|
||||
FirstWhere<T, K> op();
|
||||
|
||||
void done();
|
||||
}
|
||||
@ -115,7 +115,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
|
||||
|
||||
protected final static TimeZone s_gmtTimeZone = TimeZone.getTimeZone("GMT");
|
||||
|
||||
protected final static Map<Class<?>, GenericDao<?, ? extends Serializable>> s_daoMaps = new ConcurrentHashMap<Class<?>, GenericDao<?, ? extends Serializable>>(71);
|
||||
protected final static Map<Class<?>, GenericDaoBase<?, ? extends Serializable>> s_daoMaps = new ConcurrentHashMap<Class<?>, GenericDaoBase<?, ? extends Serializable>>(71);
|
||||
|
||||
protected Class<T> _entityBeanType;
|
||||
protected String _table;
|
||||
@ -156,9 +156,9 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
|
||||
|
||||
protected String _name;
|
||||
|
||||
public static <J> GenericDao<? extends J, ? extends Serializable> getDao(Class<J> entityType) {
|
||||
public static <J> GenericDaoBase<? extends J, ? extends Serializable> getDao(Class<J> entityType) {
|
||||
@SuppressWarnings("unchecked")
|
||||
GenericDao<? extends J, ? extends Serializable> dao = (GenericDao<? extends J, ? extends Serializable>)s_daoMaps.get(entityType);
|
||||
GenericDaoBase<? extends J, ? extends Serializable> dao = (GenericDaoBase<? extends J, ? extends Serializable>)s_daoMaps.get(entityType);
|
||||
assert dao != null : "Unable to find DAO for " + entityType + ". Are you sure you waited for the DAO to be initialized before asking for it?";
|
||||
return dao;
|
||||
}
|
||||
@ -172,6 +172,10 @@ public abstract class GenericDaoBase<T, ID extends Serializable> implements Gene
|
||||
factory.setCallback(0, builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public final Map<String, Attribute> getAllAttributes() {
|
||||
return _allAttributes;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected GenericDaoBase() {
|
||||
|
||||
32
utils/src/com/cloud/utils/db/JoinQueryBuilder.java
Normal file
32
utils/src/com/cloud/utils/db/JoinQueryBuilder.java
Normal file
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.utils.db;
|
||||
|
||||
/**
|
||||
* JoinQueryBuilder builds queries for joins between multiple tables.
|
||||
*
|
||||
*/
|
||||
public interface JoinQueryBuilder<S, T> {
|
||||
Select<S, T> selectField(Object column);
|
||||
|
||||
<J> On<S, J, T> innerJoin(Class<J> entityClazz);
|
||||
|
||||
<J> J entity(Class<J> entityClazz);
|
||||
|
||||
FirstWhere<S, T> where();
|
||||
}
|
||||
@ -66,6 +66,7 @@ public class Merovingian2 extends StandardMBean implements MerovingianMBean {
|
||||
Connection conn = null;
|
||||
try {
|
||||
conn = Transaction.getStandaloneConnectionWithException();
|
||||
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
|
||||
_concierge = new ConnectionConcierge("LockMaster", conn, true, true);
|
||||
} catch (SQLException e) {
|
||||
s_logger.error("Unable to get a new db connection", e);
|
||||
|
||||
28
utils/src/com/cloud/utils/db/NextWhere.java
Normal file
28
utils/src/com/cloud/utils/db/NextWhere.java
Normal file
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.utils.db;
|
||||
|
||||
public interface NextWhere<T, K> extends FirstWhere<T, K> {
|
||||
NextWhere<T, K> and();
|
||||
NextWhere<T, K> or();
|
||||
NextWhere<T, K> not();
|
||||
|
||||
@Override
|
||||
void done();
|
||||
|
||||
}
|
||||
22
utils/src/com/cloud/utils/db/On.java
Normal file
22
utils/src/com/cloud/utils/db/On.java
Normal file
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.utils.db;
|
||||
|
||||
public interface On<S, J, T> {
|
||||
|
||||
}
|
||||
195
utils/src/com/cloud/utils/db/QueryBuilder.java
Normal file
195
utils/src/com/cloud/utils/db/QueryBuilder.java
Normal file
@ -0,0 +1,195 @@
|
||||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.utils.db;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import net.sf.cglib.proxy.Enhancer;
|
||||
import net.sf.cglib.proxy.MethodInterceptor;
|
||||
import net.sf.cglib.proxy.MethodProxy;
|
||||
|
||||
import com.cloud.utils.Pair;
|
||||
|
||||
public class QueryBuilder<S, T> implements MethodInterceptor, SimpleQueryBuilder<S>, SelectQueryBuilder<S, T>, JoinQueryBuilder<S, T> {
|
||||
public enum Func {
|
||||
NATIVE("@", 1),
|
||||
MAX("MAX(@)", 1),
|
||||
MIN("MIN(@)", 1),
|
||||
FIRST("FIRST(@)", 1),
|
||||
LAST("LAST(@)", 1),
|
||||
SUM("SUM(@)", 1),
|
||||
COUNT("COUNT(@)", 1),
|
||||
DISTINCT("DISTINCT(@)", 1);
|
||||
|
||||
private String func;
|
||||
private int count;
|
||||
|
||||
Func(String func, int params) {
|
||||
this.func = func;
|
||||
this.count = params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return func;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
protected HashMap<Class<?>, Pair<GenericDaoBase<?,?>, Object>> _entities;
|
||||
protected ArrayList<Attribute> _specifiedAttrs = new ArrayList<Attribute>();
|
||||
protected T _resultSetClass;
|
||||
protected ArrayList<Select<S, T>> _selects;
|
||||
|
||||
public QueryBuilder(Class<T> resultSetClass, Class<?>... clazzes) {
|
||||
_entities = new HashMap<Class<?>, Pair<GenericDaoBase<?,?>, Object>>(clazzes.length);
|
||||
for (Class<?> clazz : clazzes) {
|
||||
GenericDaoBase<?,?> dao = GenericDaoBase.getDao(clazz);
|
||||
Enhancer searchEnhancer = new Enhancer();
|
||||
searchEnhancer.setSuperclass(clazz);
|
||||
searchEnhancer.setCallback(this);
|
||||
Object entity = searchEnhancer.create();
|
||||
|
||||
_entities.put(clazz, new Pair<GenericDaoBase<?, ?>, Object>(dao, entity));
|
||||
}
|
||||
}
|
||||
|
||||
protected void clean() {
|
||||
_specifiedAttrs = null;
|
||||
_entities = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for SelectQueryBuilder interface. Must specify the
|
||||
* table to be performing the query on and the result class to place it in.
|
||||
* @param entityClass entity class to do the query on.
|
||||
* @param resultSetClass result class to put the result set in.
|
||||
*/
|
||||
public QueryBuilder(Class<S> entityClass, Class<T> resultSetClass) {
|
||||
_entities = new HashMap<Class<?>, Pair<GenericDaoBase<?,?>, Object>>(1);
|
||||
GenericDaoBase<?,?> dao = GenericDaoBase.getDao(entityClass);
|
||||
Enhancer searchEnhancer = new Enhancer();
|
||||
searchEnhancer.setSuperclass(entityClass);
|
||||
searchEnhancer.setCallback(this);
|
||||
Object entity = searchEnhancer.create();
|
||||
|
||||
_entities.put(entityClass, new Pair<GenericDaoBase<?, ?>, Object>(dao, entity));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleQueryBuilder<S> selectFields(Object... fields) {
|
||||
assert _entities != null && _entities.size() == 1 : "Now you've done it....Stop casting interfaces on the QueryBuilder";
|
||||
assert _specifiedAttrs.size() > 0 : "You didn't specify any attributes";
|
||||
|
||||
if (_selects == null) {
|
||||
_selects = new ArrayList<Select<S, T>>(fields.length);
|
||||
}
|
||||
|
||||
for (Attribute attr : _specifiedAttrs) {
|
||||
_selects.add(new Select<S, T>(this, null, attr));
|
||||
}
|
||||
|
||||
_specifiedAttrs.clear();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
protected void set(GenericDaoBase<?, ?> dao , String name) {
|
||||
Attribute attr = dao.getAllAttributes().get(name);
|
||||
assert (attr != null) : "Searching for a field that's not there: " + name;
|
||||
_specifiedAttrs.add(attr);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object intercept(Object entity, Method method, Object[] args, MethodProxy proxy) throws Throwable {
|
||||
Class<?> entityClass = entity.getClass().getSuperclass();
|
||||
|
||||
Pair<GenericDaoBase<?,?>, Object> daoInfo = _entities.get(entityClass);
|
||||
assert (daoInfo != null) : "You need to specify " + entityClass + " as one of the entities in the Query";
|
||||
GenericDaoBase<?,?> dao = daoInfo.first();
|
||||
|
||||
String name = method.getName();
|
||||
if (name.startsWith("get")) {
|
||||
String fieldName = Character.toLowerCase(name.charAt(3)) + name.substring(4);
|
||||
set(dao, fieldName);
|
||||
return null;
|
||||
} else if (name.startsWith("is")) {
|
||||
String fieldName = Character.toLowerCase(name.charAt(2)) + name.substring(3);
|
||||
set(dao, fieldName);
|
||||
return null;
|
||||
} else {
|
||||
assert false : "Perhaps you need to make the method start with get or is?";
|
||||
}
|
||||
return proxy.invokeSuper(entity, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <E> E entity(Class<E> clazz) {
|
||||
return (E)_entities.get(clazz).second();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public S entity() {
|
||||
return (S)_entities.values().iterator().next().second();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FirstWhere<S, T> where() {
|
||||
return new Where<S, T>(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleQueryBuilder<S> selectAll() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public List<Attribute> getSpecifiedAttributes() {
|
||||
return _specifiedAttrs;
|
||||
}
|
||||
|
||||
public Attribute getSpecifiedAttribute() {
|
||||
assert _specifiedAttrs.size() == 1 : "You can only specify one attribute";
|
||||
return _specifiedAttrs.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Select<S, T> selectColumn(Object column) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Select<S, T> selectField(Object column) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <J> On<S, J, T> innerJoin(Class<J> entityClazz) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -123,8 +123,24 @@ public class SearchCriteria<K> {
|
||||
private final List<Object> _groupByValues;
|
||||
private final Class<K> _resultType;
|
||||
private final SelectType _selectType;
|
||||
private final QueryBuilder<?, K> _builder;
|
||||
|
||||
protected SearchCriteria(QueryBuilder<?, K> builder) {
|
||||
_builder = builder;
|
||||
_attrs = null;
|
||||
_conditions = null;
|
||||
_additionals = null;
|
||||
_counter = 0;
|
||||
_joins = null;
|
||||
_selects = null;
|
||||
_groupBy = null;
|
||||
_groupByValues = null;
|
||||
_resultType = null;
|
||||
_selectType = null;
|
||||
}
|
||||
|
||||
protected SearchCriteria(GenericSearchBuilder<?, K> sb) {
|
||||
this._builder = null;
|
||||
this._attrs = sb._attrs;
|
||||
this._conditions = sb._conditions;
|
||||
this._additionals = new ArrayList<Condition>();
|
||||
@ -322,4 +338,10 @@ public class SearchCriteria<K> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Pair<String, ArrayList<Object>> toSql() {
|
||||
StringBuilder sql = new StringBuilder();
|
||||
|
||||
return new Pair<String, ArrayList<Object>>(sql.toString(), null);
|
||||
}
|
||||
}
|
||||
|
||||
53
utils/src/com/cloud/utils/db/Select.java
Normal file
53
utils/src/com/cloud/utils/db/Select.java
Normal file
@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.utils.db;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class Select<S, T> {
|
||||
QueryBuilder<S,T> _builder;
|
||||
Class<T> _clazz;
|
||||
Attribute _attr;
|
||||
String _as;
|
||||
Field _field;
|
||||
|
||||
protected Select(QueryBuilder<S, T> builder, Class<T> clazz, Attribute attr) {
|
||||
_builder = builder;
|
||||
_clazz = clazz;
|
||||
_attr = attr;
|
||||
}
|
||||
|
||||
public QueryBuilder<S, T> into(String fieldName) {
|
||||
if (fieldName != null) {
|
||||
try {
|
||||
_field = _clazz.getDeclaredField(fieldName);
|
||||
_field.setAccessible(true);
|
||||
} catch (SecurityException e) {
|
||||
throw new RuntimeException("Unable to find " + fieldName + " in " + _clazz.getName(), e);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new RuntimeException("Unable to find " + fieldName + " in " + _clazz.getName(), e);
|
||||
}
|
||||
}
|
||||
return _builder;
|
||||
}
|
||||
|
||||
public QueryBuilder<S, T> as(String as) {
|
||||
_as = as;
|
||||
return _builder;
|
||||
}
|
||||
}
|
||||
30
utils/src/com/cloud/utils/db/SelectQueryBuilder.java
Normal file
30
utils/src/com/cloud/utils/db/SelectQueryBuilder.java
Normal file
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.utils.db;
|
||||
|
||||
/**
|
||||
* SelectQueryBuilder allows you to select a column into a class that
|
||||
* is defined.
|
||||
*/
|
||||
public interface SelectQueryBuilder<T, S> {
|
||||
Select<T, S> selectColumn(Object column);
|
||||
|
||||
T entity();
|
||||
|
||||
FirstWhere<T, S> where();
|
||||
}
|
||||
49
utils/src/com/cloud/utils/db/SimpleQueryBuilder.java
Normal file
49
utils/src/com/cloud/utils/db/SimpleQueryBuilder.java
Normal file
@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.utils.db;
|
||||
|
||||
/**
|
||||
* SimpleQueryBuilder builds queries against a single table. The
|
||||
* result is stored into the entity that represents the table.
|
||||
*
|
||||
*/
|
||||
public interface SimpleQueryBuilder<S> {
|
||||
/**
|
||||
* Select all of the columns in the entity object. This is default so
|
||||
* it's not necessary to make this method call at all.
|
||||
*/
|
||||
SimpleQueryBuilder<S> selectAll();
|
||||
|
||||
/**
|
||||
* Select the following columns
|
||||
* @param columns array of columsn to select.
|
||||
*/
|
||||
SimpleQueryBuilder<S> selectFields(Object... columns);
|
||||
|
||||
/**
|
||||
* @return the entity object we're building this query for. By using this
|
||||
* entity object, you can specify which column to select or form
|
||||
*/
|
||||
S entity();
|
||||
|
||||
/**
|
||||
* Starts the query conditionals.
|
||||
* @return
|
||||
*/
|
||||
FirstWhere<S, ?> where();
|
||||
}
|
||||
82
utils/src/com/cloud/utils/db/Where.java
Normal file
82
utils/src/com/cloud/utils/db/Where.java
Normal file
@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the GNU General Public License v3 or later.
|
||||
*
|
||||
* It is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.cloud.utils.db;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Where implements any list of search conditions.
|
||||
*
|
||||
*/
|
||||
public class Where<T, K> implements FirstWhere<T, K>, NextWhere<T, K> {
|
||||
QueryBuilder<T, K> _builder;
|
||||
List<Object> _conditions = new ArrayList<Object>();
|
||||
|
||||
protected Where(QueryBuilder<T, K> builder) {
|
||||
_builder = builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Condition<T, K> field(Object useless, String as) {
|
||||
Attribute attr = _builder.getSpecifiedAttribute();
|
||||
Condition<T, K> cond = new Condition<T, K>(this, attr, as);
|
||||
_conditions.add(cond);
|
||||
return cond;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Where<T, K> and() {
|
||||
_conditions.add(" (");
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Where<T, K> or() {
|
||||
_conditions.add(" OR ");
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NextWhere<T, K> not() {
|
||||
_conditions.add(" NOT ");
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NextWhere<T, K> text(String text, String... paramNames) {
|
||||
assert ((paramNames.length == 0 && !text.contains("?")) || (text.matches("\\?.*{" + paramNames.length + "}")));
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Condition<T, K> field(Object useless) {
|
||||
return field(useless, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FirstWhere<T, K> op() {
|
||||
_conditions.add("(");
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void done() {
|
||||
}
|
||||
}
|
||||
126
utils/test/com/cloud/utils/db/QueryBuilderTest.java
Normal file
126
utils/test/com/cloud/utils/db/QueryBuilderTest.java
Normal file
@ -0,0 +1,126 @@
|
||||
package com.cloud.utils.db;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import com.cloud.utils.component.ComponentLocator;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
|
||||
public class QueryBuilderTest extends TestCase {
|
||||
@Entity
|
||||
@Table(name="test")
|
||||
public static class TestVO {
|
||||
@Id
|
||||
@GeneratedValue(strategy=GenerationType.IDENTITY)
|
||||
long id;
|
||||
|
||||
@Column(name="int")
|
||||
int fieldInt;
|
||||
|
||||
@Column(name="long")
|
||||
Long fieldLong;
|
||||
|
||||
@Column(name="string")
|
||||
String fieldString;
|
||||
|
||||
public String getFieldString() {
|
||||
return fieldString;
|
||||
}
|
||||
|
||||
public int getFieldInt() {
|
||||
return fieldInt;
|
||||
}
|
||||
|
||||
public long getFieldLong() {
|
||||
return fieldLong;
|
||||
}
|
||||
|
||||
public TestVO() {
|
||||
}
|
||||
}
|
||||
|
||||
public static class TestDao extends GenericDaoBase<TestVO, Long> implements GenericDao<TestVO, Long> {
|
||||
protected TestDao() {
|
||||
}
|
||||
}
|
||||
|
||||
public void setup() {
|
||||
Connection conn = null;
|
||||
PreparedStatement pstmt = null;
|
||||
try {
|
||||
conn = Transaction.getStandaloneConnection();
|
||||
|
||||
pstmt = conn.prepareStatement("CREATE TABLE `cloud`.`test` (" +
|
||||
"`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT," +
|
||||
"`int` int unsigned," +
|
||||
"`long` bigint unsigned," +
|
||||
"`string` varchar(255)," +
|
||||
"PRIMARY KEY (`id`)" +
|
||||
") ENGINE=InnoDB DEFAULT CHARSET=utf8;");
|
||||
|
||||
pstmt.execute();
|
||||
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("Problem with sql", e);
|
||||
} finally {
|
||||
if (pstmt != null) {
|
||||
try {
|
||||
pstmt.close();
|
||||
} catch (SQLException e) {
|
||||
}
|
||||
}
|
||||
if (conn != null) {
|
||||
try {
|
||||
conn.close();
|
||||
} catch (SQLException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void teardown() {
|
||||
Connection conn = null;
|
||||
PreparedStatement pstmt = null;
|
||||
try {
|
||||
conn = Transaction.getStandaloneConnection();
|
||||
|
||||
pstmt = conn.prepareStatement("DROP TABLE IF EXISTS `cloud`.`test`");
|
||||
pstmt.execute();
|
||||
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("Problem with sql", e);
|
||||
} finally {
|
||||
if (pstmt != null) {
|
||||
try {
|
||||
pstmt.close();
|
||||
} catch (SQLException e) {
|
||||
}
|
||||
}
|
||||
if (conn != null) {
|
||||
try {
|
||||
conn.close();
|
||||
} catch (SQLException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testSimpleQueryBuilder() {
|
||||
TestDao dao = ComponentLocator.inject(TestDao.class);
|
||||
SimpleQueryBuilder<TestVO> qb = new QueryBuilder<TestVO, TestVO>(TestVO.class, TestVO.class);
|
||||
qb.selectFields(qb.entity().getFieldLong()).where().field(qb.entity().getFieldInt()).eq("abc");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user