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.List; 027 028import org.nuxeo.ecm.core.storage.sql.Model; 029import org.nuxeo.ecm.core.storage.sql.Row; 030import org.nuxeo.ecm.core.storage.sql.jdbc.db.Column; 031 032/** 033 * Collection IO for arrays of scalar values. 034 */ 035public class ScalarCollectionIO implements CollectionIO { 036 037 public static final CollectionIO INSTANCE = new ScalarCollectionIO(); 038 039 @Override 040 public Serializable getCurrentFromResultSet(ResultSet rs, List<Column> columns, Model model, 041 Serializable[] returnId, int[] returnPos) throws SQLException { 042 Serializable id = null; 043 Serializable value = null; 044 int i = 0; 045 for (Column column : columns) { 046 i++; 047 String key = column.getKey(); 048 Serializable v = column.getFromResultSet(rs, i); 049 if (key.equals(model.MAIN_KEY)) { 050 id = v; 051 } else if (key.equals(model.COLL_TABLE_POS_KEY)) { 052 // (the pos column is ignored, results are already ordered by id 053 // then pos) 054 } else if (key.equals(model.COLL_TABLE_VALUE_KEY)) { 055 value = v; 056 } else { 057 throw new RuntimeException(key); 058 } 059 } 060 Serializable prevId = returnId[0]; 061 returnId[0] = id; 062 int pos = (id != null && !id.equals(prevId)) ? 0 : returnPos[0] + 1; 063 returnPos[0] = pos; 064 return value; 065 } 066 067 @Override 068 public void executeInserts(PreparedStatement ps, List<Row> rows, List<Column> columns, 069 boolean supportsBatchUpdates, String sql, JDBCConnection connection) throws SQLException { 070 List<Serializable> debugValues = connection.logger.isLogEnabled() ? new ArrayList<Serializable>() : null; 071 String loggedSql = supportsBatchUpdates && rows.size() > 1 ? sql + " -- BATCHED" : sql; 072 int batch = 0; 073 for (Row row : rows) { 074 batch++; 075 Serializable id = row.id; 076 Serializable[] array = row.values; 077 for (int i = 0; i < array.length; i++) { 078 int n = 0; 079 for (Column column : columns) { 080 n++; 081 String key = column.getKey(); 082 Serializable v; 083 if (key.equals(Model.MAIN_KEY)) { 084 v = id; 085 } else if (key.equals(Model.COLL_TABLE_POS_KEY)) { 086 v = Long.valueOf((long) i); 087 } else if (key.equals(Model.COLL_TABLE_VALUE_KEY)) { 088 v = array[i]; 089 } else { 090 throw new RuntimeException(key); 091 } 092 column.setToPreparedStatement(ps, n, v); 093 if (debugValues != null) { 094 debugValues.add(v); 095 } 096 } 097 if (debugValues != null) { 098 connection.logger.logSQL(loggedSql, debugValues); 099 debugValues.clear(); 100 } 101 if (supportsBatchUpdates) { 102 ps.addBatch(); 103 if (batch % JDBCRowMapper.UPDATE_BATCH_SIZE == 0) { 104 ps.executeBatch(); 105 connection.countExecute(); 106 } 107 } else { 108 ps.execute(); 109 connection.countExecute(); 110 } 111 } 112 } 113 if (supportsBatchUpdates) { 114 ps.executeBatch(); 115 connection.countExecute(); 116 } 117 } 118 119}