jdbcCtx = new QueryOptionJdbcContext();
query.customize(jdbcCtx);
}
// activates page and offset options as there are always used in SQL requests
QueryOptionPage pag = (QueryOptionPage)query.option(QueryOptionPage.ID);
if(!pag.isPaginating()){
if(pag.isActive()){
if(limit!=Integer.MAX_VALUE){
jdbcCtx.realPageSize = limit;
}
else {
jdbcCtx.realPageSize = pag.pageSize;
}
}
else {
jdbcCtx.realPageSize = limit;
}
}else {
jdbcCtx.realPageSize = pag.pageSize;
}
QueryOptionOffset offsetOpt = (QueryOptionOffset)(query.option(QueryOptionOffset.ID));
// if local offset has been set, uses it
if(offset!=0){
offsetOpt.activate();
offsetOpt.offset = offset;
}
QueryOptionState state = (QueryOptionState)query.option(QueryOptionState.ID);
// if previousPage has detected there is no more data, simply returns an empty list
if(jdbcCtx.noMoreDataBefore){
return new ArrayList<T>();
}
if(state.isStateless()
|| (state.isStateful() && !jdbcCtx.isActive())
|| (state.isStateful() && jdbcCtx.isActive() && jdbcCtx.isClosed())) {
if(state.isStateless()){
if(pag.isPaginating()){
if(offsetOpt.isActive()){
jdbcCtx.realOffset+=offsetOpt.offset;
offsetOpt.passivate();
}else {
// keeps realOffset
}
}else {
// if page is active, immediately passivates it not to keep is active
if(pag.isActive()) {
pag.passivate();
}
if(offsetOpt.isActive()){
jdbcCtx.realOffset=offsetOpt.offset;
offsetOpt.passivate();
}else{
jdbcCtx.realOffset = 0;
}
}
} else {
if(offsetOpt.isActive()){
jdbcCtx.realOffset+=offsetOpt.offset;
offsetOpt.passivate();
}else {
// keeps realOffset
}
}
Class<T> clazz = query.getQueriedClass();
List<Object> parameters = new ArrayList<Object>();
StringBuilder sql = JdbcDBUtils.buildSqlSelect(query);
appendSqlWhere(query, sql, parameters);
JdbcDBUtils.appendSqlOrder(query, sql);
JdbcDBUtils.appendSqlLimitOffset(query, sql, parameters);
//sql.append(suffix);
PreparedStatement statement = null;
ResultSet rs = null;
try {
statement = createStatement(sql.toString(), parameters);
if(pag.isPaginating()) {
// this is just a hint to the DB so wonder if it should be used
statement.setFetchSize(jdbcCtx.realPageSize);
}
rs = statement.executeQuery();
List<T> result = JdbcMappingUtils.mapList(clazz, rs, ClassInfo.getClassInfo(clazz).tableName,
JdbcMappingUtils.getJoinFields(query), jdbcCtx.realPageSize);
if(pag.isPaginating()){
if(result.size() == 0){
jdbcCtx.noMoreDataAfter = true;
}
else {
jdbcCtx.noMoreDataAfter = false;
}
}else {
if(state.isStateful()){
jdbcCtx.realOffset += result.size();
}
}
if(state.isStateless()){
JdbcDBUtils.closeResultSet(rs);
JdbcDBUtils.closeStatementAndConnection(this, statement);
}else {
Integer offsetParamIdx = parameters.size();
Integer limitParamIdx = offsetParamIdx - 1;
// store indexes of offset and limit for reuse
jdbcCtx.activate();
jdbcCtx.statement = statement;
jdbcCtx.limitParamIdx = limitParamIdx;
jdbcCtx.offsetParamIdx = offsetParamIdx;
}
return result;
}
catch(SQLException e) {
JdbcDBUtils.closeResultSet(rs);
JdbcDBUtils.closeStatementAndConnection(this, statement);
throw new SienaException(e);
}
}else {
// payload has been initialized so goes on
Class<T> clazz = query.getQueriedClass();
if(offsetOpt.isActive()){
jdbcCtx.realOffset+=offsetOpt.offset;
offsetOpt.passivate();
}else {
// keeps realOffset
}
ResultSet rs = null;
try {
// when paginating, should update limit and offset
//if(pag.isActive()){
// update limit and offset
jdbcCtx.statement.setObject(jdbcCtx.limitParamIdx, jdbcCtx.realPageSize);
//}
//if(offsetOpt.isActive()){
jdbcCtx.statement.setObject(jdbcCtx.offsetParamIdx, jdbcCtx.realOffset);
//}
rs = jdbcCtx.statement.executeQuery();
List<T> result = JdbcMappingUtils.mapList(clazz, rs, ClassInfo.getClassInfo(clazz).tableName,
JdbcMappingUtils.getJoinFields(query), jdbcCtx.realPageSize);
// increases offset
if(pag.isPaginating()){
if(result.size() == 0){
jdbcCtx.noMoreDataAfter = true;
}
else {
jdbcCtx.noMoreDataAfter = false;