001/* 002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Florent Guillaume 018 */ 019package org.nuxeo.ecm.core.storage.sql.jdbc; 020 021import java.io.Serializable; 022import java.sql.PreparedStatement; 023import java.sql.ResultSet; 024import java.sql.SQLException; 025import java.util.ArrayList; 026import java.util.Calendar; 027import java.util.Iterator; 028import java.util.List; 029 030import org.nuxeo.ecm.core.storage.sql.ACLRow; 031import org.nuxeo.ecm.core.storage.sql.Model; 032import org.nuxeo.ecm.core.storage.sql.RowMapper.RowUpdate; 033import org.nuxeo.ecm.core.storage.sql.jdbc.db.Column; 034 035/** 036 * Collection IO for arrays of ACLs. 037 */ 038public class ACLCollectionIO implements CollectionIO { 039 040 /** Whether we always write all the row elements in a RowUpdate or just the values starting from pos. */ 041 protected final boolean insertAll; 042 043 public ACLCollectionIO(boolean insertAll) { 044 this.insertAll = insertAll; 045 } 046 047 @Override 048 public ACLRow getCurrentFromResultSet(ResultSet rs, List<Column> columns, Model model, Serializable[] returnId, 049 int[] returnPos) throws SQLException { 050 Serializable id = null; 051 String name = null; 052 boolean grant = false; 053 String permission = null; 054 String creator = null; 055 Calendar begin = null; 056 Calendar end = null; 057 String user = null; 058 String group = null; 059 Long status = null; 060 int i = 0; 061 for (Column column : columns) { 062 i++; 063 String key = column.getKey(); 064 Serializable v = column.getFromResultSet(rs, i); 065 switch (key) { 066 case Model.MAIN_KEY: 067 id = v; 068 break; 069 case Model.ACL_NAME_KEY: 070 name = (String) v; 071 break; 072 case Model.ACL_GRANT_KEY: 073 grant = v == null ? false : (Boolean) v; 074 break; 075 case Model.ACL_PERMISSION_KEY: 076 permission = (String) v; 077 break; 078 case Model.ACL_CREATOR_KEY: 079 creator = (String) v; 080 break; 081 case Model.ACL_BEGIN_KEY: 082 begin = (Calendar) v; 083 break; 084 case Model.ACL_END_KEY: 085 end = (Calendar) v; 086 break; 087 case Model.ACL_USER_KEY: 088 user = (String) v; 089 break; 090 case Model.ACL_GROUP_KEY: 091 group = (String) v; 092 break; 093 case Model.ACL_STATUS_KEY: 094 status = (Long) v; 095 break; 096 case Model.ACL_POS_KEY: 097 // ignore, query already sorts by pos 098 break; 099 default: 100 throw new RuntimeException(key); 101 } 102 } 103 Serializable prevId = returnId[0]; 104 returnId[0] = id; 105 int pos = (id != null && !id.equals(prevId)) ? 0 : returnPos[0] + 1; 106 returnPos[0] = pos; 107 return new ACLRow(pos, name, grant, permission, user, group, creator, begin, end, status); 108 } 109 110 @Override 111 public void executeInserts(PreparedStatement ps, List<RowUpdate> rowus, List<Column> columns, 112 boolean supportsBatchUpdates, String sql, JDBCConnection connection) throws SQLException { 113 List<Serializable> debugValues = connection.logger.isLogEnabled() ? new ArrayList<>() : null; 114 boolean batched = supportsBatchUpdates && rowus.size() > 1; 115 String loggedSql = batched ? sql + " -- BATCHED" : sql; 116 int batch = 0; 117 for (Iterator<RowUpdate> rowIt = rowus.iterator(); rowIt.hasNext();) { 118 RowUpdate rowu = rowIt.next(); 119 int start; 120 if (rowu.pos == -1 || insertAll) { 121 start = 0; 122 } else { 123 start = rowu.pos; 124 } 125 Serializable id = rowu.row.id; 126 Serializable[] array = rowu.row.values; 127 for (int i = start; i < array.length; i++) { 128 ACLRow acl = (ACLRow) array[i]; 129 int n = 0; 130 for (Column column : columns) { 131 n++; 132 String key = column.getKey(); 133 Serializable v; 134 switch (key) { 135 case Model.MAIN_KEY: 136 v = id; 137 break; 138 case Model.ACL_POS_KEY: 139 v = (long) acl.pos; 140 break; 141 case Model.ACL_NAME_KEY: 142 v = acl.name; 143 break; 144 case Model.ACL_GRANT_KEY: 145 v = acl.grant; 146 break; 147 case Model.ACL_PERMISSION_KEY: 148 v = acl.permission; 149 break; 150 case Model.ACL_CREATOR_KEY: 151 v = acl.creator; 152 break; 153 case Model.ACL_BEGIN_KEY: 154 v = acl.begin; 155 break; 156 case Model.ACL_END_KEY: 157 v = acl.end; 158 break; 159 case Model.ACL_STATUS_KEY: 160 v = acl.status; 161 break; 162 case Model.ACL_USER_KEY: 163 v = acl.user; 164 break; 165 case Model.ACL_GROUP_KEY: 166 v = acl.group; 167 break; 168 default: 169 throw new RuntimeException(key); 170 } 171 column.setToPreparedStatement(ps, n, v); 172 if (debugValues != null) { 173 debugValues.add(v); 174 } 175 } 176 if (debugValues != null) { 177 connection.logger.logSQL(loggedSql, debugValues); 178 debugValues.clear(); 179 } 180 if (batched) { 181 ps.addBatch(); 182 batch++; 183 if (batch % JDBCRowMapper.UPDATE_BATCH_SIZE == 0 || !rowIt.hasNext()) { 184 ps.executeBatch(); 185 connection.countExecute(); 186 } 187 } else { 188 ps.execute(); 189 connection.countExecute(); 190 } 191 } 192 } 193 } 194 195}