/*
* (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
*
* 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.
*
* Contributors:
* Florent Guillaume
*/
package org.nuxeo.ecm.core.storage.sql.jdbc;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
import org.nuxeo.ecm.core.storage.sql.ACLRow;
import org.nuxeo.ecm.core.storage.sql.Model;
import org.nuxeo.ecm.core.storage.sql.RowMapper.RowUpdate;
import org.nuxeo.ecm.core.storage.sql.jdbc.db.Column;
/**
* Collection IO for arrays of ACLs.
*/
public class ACLCollectionIO implements CollectionIO {
/** Whether we always write all the row elements in a RowUpdate or just the values starting from pos. */
protected final boolean insertAll;
public ACLCollectionIO(boolean insertAll) {
this.insertAll = insertAll;
}
@Override
public ACLRow getCurrentFromResultSet(ResultSet rs, List<Column> columns, Model model, Serializable[] returnId,
int[] returnPos) throws SQLException {
Serializable id = null;
String name = null;
boolean grant = false;
String permission = null;
String creator = null;
Calendar begin = null;
Calendar end = null;
String user = null;
String group = null;
Long status = null;
int i = 0;
for (Column column : columns) {
i++;
String key = column.getKey();
Serializable v = column.getFromResultSet(rs, i);
switch (key) {
case Model.MAIN_KEY:
id = v;
break;
case Model.ACL_NAME_KEY:
name = (String) v;
break;
case Model.ACL_GRANT_KEY:
grant = v == null ? false : (Boolean) v;
break;
case Model.ACL_PERMISSION_KEY:
permission = (String) v;
break;
case Model.ACL_CREATOR_KEY:
creator = (String) v;
break;
case Model.ACL_BEGIN_KEY:
begin = (Calendar) v;
break;
case Model.ACL_END_KEY:
end = (Calendar) v;
break;
case Model.ACL_USER_KEY:
user = (String) v;
break;
case Model.ACL_GROUP_KEY:
group = (String) v;
break;
case Model.ACL_STATUS_KEY:
status = (Long) v;
break;
case Model.ACL_POS_KEY:
// ignore, query already sorts by pos
break;
default:
throw new RuntimeException(key);
}
}
Serializable prevId = returnId[0];
returnId[0] = id;
int pos = (id != null && !id.equals(prevId)) ? 0 : returnPos[0] + 1;
returnPos[0] = pos;
return new ACLRow(pos, name, grant, permission, user, group, creator, begin, end, status);
}
@Override
public void executeInserts(PreparedStatement ps, List<RowUpdate> rowus, List<Column> columns,
boolean supportsBatchUpdates, String sql, JDBCConnection connection) throws SQLException {
List<Serializable> debugValues = connection.logger.isLogEnabled() ? new ArrayList<Serializable>() : null;
boolean batched = supportsBatchUpdates && rowus.size() > 1;
String loggedSql = batched ? sql + " -- BATCHED" : sql;
int batch = 0;
for (Iterator<RowUpdate> rowIt = rowus.iterator(); rowIt.hasNext();) {
RowUpdate rowu = rowIt.next();
int start;
if (rowu.pos == -1 || insertAll) {
start = 0;
} else {
start = rowu.pos;
}
Serializable id = rowu.row.id;
Serializable[] array = rowu.row.values;
for (int i = start; i < array.length; i++) {
ACLRow acl = (ACLRow) array[i];
int n = 0;
for (Column column : columns) {
n++;
String key = column.getKey();
Serializable v;
switch (key) {
case Model.MAIN_KEY:
v = id;
break;
case Model.ACL_POS_KEY:
v = (long) acl.pos;
break;
case Model.ACL_NAME_KEY:
v = acl.name;
break;
case Model.ACL_GRANT_KEY:
v = acl.grant;
break;
case Model.ACL_PERMISSION_KEY:
v = acl.permission;
break;
case Model.ACL_CREATOR_KEY:
v = acl.creator;
break;
case Model.ACL_BEGIN_KEY:
v = acl.begin;
break;
case Model.ACL_END_KEY:
v = acl.end;
break;
case Model.ACL_STATUS_KEY:
v = acl.status;
break;
case Model.ACL_USER_KEY:
v = acl.user;
break;
case Model.ACL_GROUP_KEY:
v = acl.group;
break;
default:
throw new RuntimeException(key);
}
column.setToPreparedStatement(ps, n, v);
if (debugValues != null) {
debugValues.add(v);
}
}
if (debugValues != null) {
connection.logger.logSQL(loggedSql, debugValues);
debugValues.clear();
}
if (batched) {
ps.addBatch();
batch++;
if (batch % JDBCRowMapper.UPDATE_BATCH_SIZE == 0 || !rowIt.hasNext()) {
ps.executeBatch();
connection.countExecute();
}
} else {
ps.execute();
connection.countExecute();
}
}
}
}
}