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}