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.List; 028 029import org.nuxeo.ecm.core.storage.sql.ACLRow; 030import org.nuxeo.ecm.core.storage.sql.Model; 031import org.nuxeo.ecm.core.storage.sql.RowMapper.RowUpdate; 032import org.nuxeo.ecm.core.storage.sql.jdbc.db.Column; 033 034/** 035 * Collection IO for arrays of ACLs. 036 */ 037public class ACLCollectionIO implements CollectionIO { 038 039 /** Whether we always write all the row elements in a RowUpdate or just the values starting from pos. */ 040 protected final boolean insertAll; 041 042 public ACLCollectionIO(boolean insertAll) { 043 this.insertAll = insertAll; 044 } 045 046 @Override 047 public ACLRow getCurrentFromResultSet(ResultSet rs, List<Column> columns, Model model, Serializable[] returnId, 048 int[] returnPos) throws SQLException { 049 Serializable id = null; 050 String name = null; 051 boolean grant = false; 052 String permission = null; 053 String creator = null; 054 Calendar begin = null; 055 Calendar end = null; 056 String user = null; 057 String group = null; 058 Long status = null; 059 int i = 0; 060 for (Column column : columns) { 061 i++; 062 String key = column.getKey(); 063 Serializable v = column.getFromResultSet(rs, i); 064 switch (key) { 065 case Model.MAIN_KEY: 066 id = v; 067 break; 068 case Model.ACL_NAME_KEY: 069 name = (String) v; 070 break; 071 case Model.ACL_GRANT_KEY: 072 grant = v == null ? false : (Boolean) v; 073 break; 074 case Model.ACL_PERMISSION_KEY: 075 permission = (String) v; 076 break; 077 case Model.ACL_CREATOR_KEY: 078 creator = (String) v; 079 break; 080 case Model.ACL_BEGIN_KEY: 081 begin = (Calendar) v; 082 break; 083 case Model.ACL_END_KEY: 084 end = (Calendar) v; 085 break; 086 case Model.ACL_USER_KEY: 087 user = (String) v; 088 break; 089 case Model.ACL_GROUP_KEY: 090 group = (String) v; 091 break; 092 case Model.ACL_STATUS_KEY: 093 status = (Long) v; 094 break; 095 case Model.ACL_POS_KEY: 096 // ignore, query already sorts by pos 097 break; 098 default: 099 throw new RuntimeException(key); 100 } 101 } 102 Serializable prevId = returnId[0]; 103 returnId[0] = id; 104 int pos = (id != null && !id.equals(prevId)) ? 0 : returnPos[0] + 1; 105 returnPos[0] = pos; 106 return new ACLRow(pos, name, grant, permission, user, group, creator, begin, end, status); 107 } 108 109 @Override 110 public void executeInserts(PreparedStatement ps, List<RowUpdate> rowus, List<Column> columns, 111 boolean supportsBatchUpdates, String sql, JDBCConnection connection) throws SQLException { 112 List<Serializable> debugValues = connection.logger.isLogEnabled() ? new ArrayList<Serializable>() : null; 113 String loggedSql = supportsBatchUpdates ? sql + " -- BATCHED" : sql; 114 int batch = 0; 115 for (RowUpdate rowu : rowus) { 116 batch++; 117 int start; 118 if (rowu.pos == -1 || insertAll) { 119 start = 0; 120 } else { 121 start = rowu.pos; 122 } 123 Serializable id = rowu.row.id; 124 Serializable[] array = rowu.row.values; 125 for (int i = start; i < array.length; i++) { 126 ACLRow acl = (ACLRow) array[i]; 127 int n = 0; 128 for (Column column : columns) { 129 n++; 130 String key = column.getKey(); 131 Serializable v; 132 switch (key) { 133 case Model.MAIN_KEY: 134 v = id; 135 break; 136 case Model.ACL_POS_KEY: 137 v = (long) acl.pos; 138 break; 139 case Model.ACL_NAME_KEY: 140 v = acl.name; 141 break; 142 case Model.ACL_GRANT_KEY: 143 v = acl.grant; 144 break; 145 case Model.ACL_PERMISSION_KEY: 146 v = acl.permission; 147 break; 148 case Model.ACL_CREATOR_KEY: 149 v = acl.creator; 150 break; 151 case Model.ACL_BEGIN_KEY: 152 v = acl.begin; 153 break; 154 case Model.ACL_END_KEY: 155 v = acl.end; 156 break; 157 case Model.ACL_STATUS_KEY: 158 v = acl.status; 159 break; 160 case Model.ACL_USER_KEY: 161 v = acl.user; 162 break; 163 case Model.ACL_GROUP_KEY: 164 v = acl.group; 165 break; 166 default: 167 throw new RuntimeException(key); 168 } 169 column.setToPreparedStatement(ps, n, v); 170 if (debugValues != null) { 171 debugValues.add(v); 172 } 173 } 174 if (debugValues != null) { 175 connection.logger.logSQL(loggedSql, debugValues); 176 debugValues.clear(); 177 } 178 if (supportsBatchUpdates) { 179 ps.addBatch(); 180 if (batch % JDBCRowMapper.UPDATE_BATCH_SIZE == 0) { 181 ps.executeBatch(); 182 connection.countExecute(); 183 } 184 } else { 185 ps.execute(); 186 connection.countExecute(); 187 } 188 } 189 } 190 if (supportsBatchUpdates) { 191 ps.executeBatch(); 192 connection.countExecute(); 193 } 194 } 195 196}