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}