Projects >> nuxeo-core >>4d8f8c79604a2c2d2c1c97fefeb005f35ca4f28a

Chunk
Conflicting content
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
<<<<<<< HEAD
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
=======
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
>>>>>>> f5ac6c074337f5be4ab732b46312fe57d3803bd6

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
Solution content
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
File
H2Functions.java
Developer's decision
Version 2
Kind of conflict
Import
Chunk
Conflicting content
    }

        }
    }

<<<<<<< HEAD
    protected static String getLocalReadAcl(Connection conn, String id)
            throws SQLException {
        String sql = "SELECT \"GRANT\", \"USER\"" //
                + " FROM ACLS" //
                + " WHERE" //
                + "   \"ID\" = '"
                + id
                + "'"//
                + "   AND \"PERMISSION\" IN ('Read', 'ReadWrite', 'Everything', 'Browse')"
                + " ORDER BY \"POS\"";
        if (isLogEnabled()) {
            logDebug(sql);
        }
        PreparedStatement ps = conn.prepareStatement(sql);
        ResultSet rs = ps.executeQuery();
        StringBuffer readAcl = new StringBuffer();
        try {
            while (rs.next()) {
                Boolean grant = rs.getBoolean(1);
                String op;
                if (grant) {
                    op = rs.getString(2);
                } else {
                    op = '-' + rs.getString(2);
                }
                if (readAcl.length() == 0) {
                    readAcl.append(op);
                } else {
                    readAcl.append("," + op);
                }
            }
        } finally {
            if (ps != null) {
                ps.close();
            }
        }
        return readAcl.toString();
    public static String getReadAcl(Connection conn, String id)
            throws SQLException {
        String localReadAcl;
        StringBuffer readAcl = new StringBuffer();

        PreparedStatement ps1 = null;
        PreparedStatement ps2 = null;
        try {
            ps1 = conn.prepareStatement("SELECT PARENTID FROM HIERARCHY WHERE ID = ?;");
            boolean first = true;
            do {
                // local acl
                localReadAcl = getLocalReadAcl(conn, id);
                if (localReadAcl != null && (localReadAcl.length() > 0)) {
                    if (readAcl.length() == 0) {
                        readAcl.append(localReadAcl);
                    } else {
                        readAcl.append(',' + localReadAcl);
                    }
                }
                // get parent
                ps1.setObject(1, id);
                ResultSet rs = ps1.executeQuery();
                String newId;
                if (rs.next()) {
                    newId = (String) rs.getObject(1);
                    if (rs.wasNull()) {
                        newId = null;
                    }
                } else {
                    // no such id
                    newId = null;
                }
                if (first && newId == null) {
                    // there is no parent for the first level
                    // we may have a version on our hands, find the live doc
                    ps2 = conn.prepareStatement("SELECT VERSIONABLEID FROM VERSIONS WHERE ID = ?;");
                    ps2.setObject(1, id);
                    rs = ps2.executeQuery();
                    if (rs.next()) {
                        newId = (String) rs.getObject(1);
                        if (rs.wasNull()) {
                            newId = null;
                        }
                    } else {
                        // no such id
                        newId = null;
                    }
                }
                first = false;
                id = newId;
            } while (id != null);
        } finally {
            if (ps1 != null) {
                ps1.close();
            }
            if (ps2 != null) {
                ps2.close();
            }
        }
        return readAcl.toString();
    }

    public static ResultSet getReadAclsFor(Connection conn, String principals)
            throws SQLException {
        DatabaseMetaData meta = conn.getMetaData();
        SimpleResultSet result = new SimpleResultSet();
        result.addColumn("ID", Types.VARCHAR, 0, 0); // String id
        if (meta.getURL().startsWith("jdbc:columnlist:")) {
            // this is just to query the result set columns
            return result;
        }
        if (principals == null) {
            return result;
        }
        Set principalsList = split(principals);
        Set blackList = new HashSet();
        for (String user : principalsList) {
            blackList.add('-' + user);
        }
        // log.debug("getReadAclFor " + principals);
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = conn.prepareStatement("SELECT \"ID\", \"ACL\" FROM READ_ACLS");
            rs = ps.executeQuery();
            while (rs.next()) {
                String id = rs.getString(1);
                String[] acl = rs.getString(2).split(",");
                for (String ace : acl) {
                    // log.debug("ace: " + ace);
                    if (principalsList.contains(ace)) {
                        result.addRow(new Object[] { id });
                        // log.debug("allowed: " + id);
                    } else if (blackList.contains(ace)) {
                        // log.debug("deny: " + id);
                        break;
                    }
                }
            }
        } finally {
            if (rs != null) {
                rs.close();
            }
            if (ps != null) {
                ps.close();
            }
        }
        return result;
    }

    public static class LogAclsModified implements org.h2.api.Trigger,
            CloseListener {

        private String idName = "ID";

        private int idIndex;

        private int idType;

        /**
         * Trigger interface: initialization.
         */
        public void init(Connection conn, String schema, String triggerName,
                String table, boolean before, int opType) throws SQLException {
            ResultSet rs = null;
            try {
                DatabaseMetaData meta = conn.getMetaData();
                rs = meta.getColumns(null, schema, table, idName);
                if (!rs.next()) {
                    if (oldRow == null) {
                    throw new SQLException("No id key for: " + schema + '.'
                            + table);
                }
                idType = rs.getInt("DATA_TYPE");
                idIndex = rs.getInt("ORDINAL_POSITION") - 1;
            } finally {
                if (rs != null) {
                    rs.close();
                }
            }
        }

        /**
         * Trigger interface.
         */
        public void fire(Connection conn, Object[] oldRow, Object[] newRow)
                throws SQLException {
            if (newRow != null) {
                PreparedStatement ps = null;
                try {
                    ps = conn.prepareStatement("INSERT INTO hierarchy_modified_acl VALUES(?, ?);");
                    ps.setString(2, "f");
                    if (oldRow != null) {
                        // update or delete
                        ps.setString(1, oldRow[idIndex].toString());
                    } else {
                        // insert
                        ps.setString(1, newRow[idIndex].toString());
                    }
                    ps.executeUpdate();
                } finally {
                    if (ps != null) {
                        ps.close();
                    }
                }
            }
        }

        public void close() throws SQLException {
        }

        public void remove() {
        }

    }

    public static class LogHierarchyModified implements org.h2.api.Trigger,
            CloseListener {
        private String idName = "ID";

        private int idIndex;

        private int idType;

        private String parentIdName = "PARENTID";

        private int parentIdIndex;

        /**
         * Trigger interface: initialization.
         */
        public void init(Connection conn, String schema, String triggerName,
                String table, boolean before, int opType) throws SQLException {
            ResultSet rs = null;
            try {
                DatabaseMetaData meta = conn.getMetaData();
                rs = meta.getColumns(null, schema, table, idName);
                if (!rs.next()) {
                    throw new SQLException("No id key for: " + schema + '.'
                            + table);
                }
                idType = rs.getInt("DATA_TYPE");
                idIndex = rs.getInt("ORDINAL_POSITION") - 1;
                rs.close();
                rs = meta.getColumns(null, schema, table, parentIdName);
                if (!rs.next()) {
                    throw new SQLException("No parentid for in " + schema + '.'
                            + table);
                }
                parentIdIndex = rs.getInt("ORDINAL_POSITION") - 1;
            } finally {
                if (rs != null) {
                    rs.close();
                }
            }

        }

        /**
         * Trigger interface.
         */
        public void fire(Connection conn, Object[] oldRow, Object[] newRow)
                throws SQLException {
            if (newRow != null) {
                PreparedStatement ps = null;
                try {
                    ps = conn.prepareStatement("INSERT INTO hierarchy_modified_acl VALUES(?, ?);");
                    ps.setString(1, newRow[idIndex].toString());
                        // Insert
                        ps.setString(2, "t");
                        ps.executeUpdate();
                    } else if (oldRow[parentIdIndex] != newRow[parentIdIndex]) {
                        // Update with new parent
                        ps.setString(2, "f");
                        ps.executeUpdate();
                    }
                } finally {
                    if (ps != null) {
                        ps.close();
                    }
                }
            }
        }

        public void close() throws SQLException {
        }

        public void remove() {
        }

    }

    public static ResultSet rebuildReadAcls(Connection conn)
            throws SQLException {
        SimpleResultSet result = new SimpleResultSet();
        PreparedStatement ps = null;
        try {
            ps = conn.prepareStatement("TRUNCATE TABLE hierarchy_read_acl;");
            ps.executeUpdate();
            ps = conn.prepareStatement("INSERT INTO hierarchy_read_acl" //
                    + "  SELECT id, nx_get_read_acl(id)"
                    + "  FROM (SELECT DISTINCT(id) AS id FROM hierarchy) AS uids;");
            ps.executeUpdate();
            ps = conn.prepareStatement("TRUNCATE TABLE read_acls;");
            ps.executeUpdate();
            // TODO: use md5 of the acl as key
            ps = conn.prepareStatement("INSERT INTO read_acls" //
                    + "  SELECT acl, acl" //
                    + "  FROM (SELECT DISTINCT(nx_get_read_acl(id)) AS acl" //
                    + "        FROM  (SELECT DISTINCT(id) AS id" //
                    + "               FROM acls) AS uids) AS read_acls_input;");
            ps.executeUpdate();
            ps = conn.prepareStatement("TRUNCATE TABLE hierarchy_modified_acl;");
            ps.executeUpdate();
        } finally {
            if (ps != null) {
                ps.close();
            }
        }
        return result;
    }

    public static ResultSet updateReadAcls(Connection conn) throws SQLException {
        SimpleResultSet result = new SimpleResultSet();
        PreparedStatement ps = null;
        int rowCount = 0;
        try {
            ps = conn.prepareStatement("TRUNCATE TABLE read_acls;");
            ps.executeUpdate();
            // TODO: use md5 of the acl as key
            ps = conn.prepareStatement("INSERT INTO read_acls" //
                    + " SELECT acl, acl" //
                    + " FROM (SELECT DISTINCT(nx_get_read_acl(id)) AS acl" //
                    + "       FROM  (SELECT DISTINCT(id) AS id" //
                    + "              FROM acls) AS uids) AS read_acls_input;");
            ps.executeUpdate();

            // New hierarchy_read_acl entry
            ps = conn.prepareStatement("INSERT INTO hierarchy_read_acl" //
                    + " SELECT id, nx_get_read_acl(id)" //
                    + " FROM (SELECT DISTINCT(id) AS id" //
                    + "   FROM hierarchy_modified_acl" //
                    + "   WHERE is_new AND" //
                    + "     EXISTS (SELECT 1 FROM hierarchy WHERE hierarchy_modified_acl.id=hierarchy.id)) AS uids;");
            rowCount = ps.executeUpdate();
            ps = conn.prepareStatement("DELETE FROM hierarchy_modified_acl WHERE is_new;");
            ps.executeUpdate();
            // Update hierarchy_read_acl entry
            // Mark acl that need to be updated (set to NULL)
            ps = conn.prepareStatement("UPDATE hierarchy_read_acl SET acl_id = NULL WHERE id IN (" //
                    + " SELECT DISTINCT(id) AS id FROM hierarchy_modified_acl WHERE NOT is_new);");
            rowCount = ps.executeUpdate();
            ps = conn.prepareStatement("DELETE FROM hierarchy_modified_acl WHERE NOT is_new;");
            ps.executeUpdate();
            ps = conn.prepareStatement("UPDATE hierarchy_read_acl SET acl_id = NULL WHERE id IN (" //
                    + " SELECT h.id" //
                    + " FROM hierarchy AS h" //
                    + " LEFT JOIN hierarchy_read_acl AS r ON h.id = r.id" //
                    + " WHERE r.acl_id IS NOT NULL" //
                    + " AND h.parentid IN (SELECT id FROM hierarchy_read_acl WHERE acl_id IS NULL));");
            // Mark all childrens
            do {
                rowCount = ps.executeUpdate();
            } while (rowCount > 0);
            // Update hierarchy_read_acl acl_ids
            // TODO use the md5 for acl_id
            ps = conn.prepareStatement("UPDATE hierarchy_read_acl SET acl_id = nx_get_read_acl(id) WHERE acl_id IS NULL;");
            ps.executeUpdate();
        } finally {
            if (ps != null) {
                ps.close();
            }
        }

        return result;
    }
=======
    /**
     * Rebuild the complete descendants tree.
     */

    public static void initDescendants(Connection conn) throws SQLException {
        String sql;
        LinkedList todo = new LinkedList();

        // find roots
        Statement s = conn.createStatement();
        sql = "SELECT ID FROM REPOSITORIES";
        logDebug(sql);
        ResultSet rs = s.executeQuery(sql);
        while (rs.next()) {
            String rootId = rs.getString(1);
            todo.add(rootId);
        }
        rs.close();
        log.trace("SQL:   -> " + todo);
        if (todo.size() == 0) {
            // db not yet initialized, ignore
            s.close();
            return;
        }

        // truncate table
        String table = "DESCENDANTS";
        sql = String.format("TRUNCATE TABLE %s", table);
        logDebug(sql);
        s.execute(sql);
        s.close();

        // traverse from roots
        Map> ancestors = new HashMap>();
        Map> descendants = new HashMap>();
        do {
            String p = todo.remove();
            sql = "SELECT ID FROM HIERARCHY WHERE PARENTID = ? AND ISPROPERTY = 0";
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setString(1, p);
            // logDebug(sql, p);
            rs = ps.executeQuery();
            // for each child
            while (rs.next()) {
                String c = rs.getString(1);
                todo.add(c);
                // child's ancestors
                Set cans = ancestors.get(c);
                if (cans == null) {
                    ancestors.put(c, cans = new HashSet());
                }
                Set pans = ancestors.get(p);
                if (pans != null) {
                    cans.addAll(pans);
                }
                cans.add(p);
                // all ancestors have it as descendant
                for (String pp : cans) {
                    Set desc = descendants.get(pp);
                    if (desc == null) {
                        descendants.put(pp, desc = new HashSet());
                    }
                    desc.add(c);
                }
            }
            ps.close();
        } while (!todo.isEmpty());

        // insert descendants into table
        sql = String.format("INSERT INTO %s (ID, DESCENDANTID) VALUES (?, ?)",
                table);
        PreparedStatement ps = conn.prepareStatement(sql);
        int n = 0;
        for (Entry> e : descendants.entrySet()) {
            String p = e.getKey();
            for (String c : e.getValue()) {
                ps.setString(1, p);
                ps.setString(2, c);
                // logDebug(sql, p, c);
                ps.execute();
                n++;
            }
        }
        logDebug(String.format("-- inserted %s rows into %s", Long.valueOf(n),
                table));
        ps.close();
    }

>>>>>>> f5ac6c074337f5be4ab732b46312fe57d3803bd6
}
Solution content
        }
                }
        }
    }

    /**
     * Rebuild the complete descendants tree.
     */

    public static void initDescendants(Connection conn) throws SQLException {
        String sql;
        LinkedList todo = new LinkedList();

        // find roots
        Statement s = conn.createStatement();
        sql = "SELECT ID FROM REPOSITORIES";
        logDebug(sql);
        ResultSet rs = s.executeQuery(sql);
        while (rs.next()) {
            String rootId = rs.getString(1);
            todo.add(rootId);
        }
        rs.close();
        log.trace("SQL:   -> " + todo);
        if (todo.size() == 0) {
            // db not yet initialized, ignore
            s.close();
            return;
        }

        // truncate table
        String table = "DESCENDANTS";
        sql = String.format("TRUNCATE TABLE %s", table);
        logDebug(sql);
        s.execute(sql);
        s.close();

        // traverse from roots
        Map> ancestors = new HashMap>();
        Map> descendants = new HashMap>();
        do {
            String p = todo.remove();
            sql = "SELECT ID FROM HIERARCHY WHERE PARENTID = ? AND ISPROPERTY = 0";
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setString(1, p);
            // logDebug(sql, p);
            rs = ps.executeQuery();
            // for each child
            while (rs.next()) {
                String c = rs.getString(1);
                todo.add(c);
                // child's ancestors
                Set cans = ancestors.get(c);
                if (cans == null) {
                    ancestors.put(c, cans = new HashSet());
                Set pans = ancestors.get(p);
                if (pans != null) {
                    cans.addAll(pans);
                }
                cans.add(p);
                // all ancestors have it as descendant
                for (String pp : cans) {
                    Set desc = descendants.get(pp);
                    if (desc == null) {
                        descendants.put(pp, desc = new HashSet());
                    }
                    desc.add(c);
                }
            }
            ps.close();
        } while (!todo.isEmpty());

        // insert descendants into table
        sql = String.format("INSERT INTO %s (ID, DESCENDANTID) VALUES (?, ?)",
                table);
        PreparedStatement ps = conn.prepareStatement(sql);
        int n = 0;
        for (Entry> e : descendants.entrySet()) {

            String p = e.getKey();
            for (String c : e.getValue()) {
                ps.setString(1, p);
                ps.setString(2, c);
                // logDebug(sql, p, c);
                ps.execute();
                n++;
            }
        }
        logDebug(String.format("-- inserted %s rows into %s", Long.valueOf(n),
                table));
        ps.close();
    }

    protected static String getLocalReadAcl(Connection conn, String id)
            throws SQLException {
        String sql = "SELECT \"GRANT\", \"USER\"" //
                + " FROM ACLS" //
                + " WHERE" //
                + "   \"ID\" = '"
                + id
                + "'"//
                + "   AND \"PERMISSION\" IN ('Read', 'ReadWrite', 'Everything', 'Browse')"
                + " ORDER BY \"POS\"";
        if (isLogEnabled()) {
            logDebug(sql);
        }
        PreparedStatement ps = conn.prepareStatement(sql);
        ResultSet rs = ps.executeQuery();
        StringBuffer readAcl = new StringBuffer();
        try {
            while (rs.next()) {
                Boolean grant = rs.getBoolean(1);
                String op;
                if (grant) {
                    op = rs.getString(2);
                } else {
                    op = '-' + rs.getString(2);
                }
                if (readAcl.length() == 0) {
                    readAcl.append(op);
                } else {
                    readAcl.append("," + op);
                }
            }
        } finally {
            if (ps != null) {
                ps.close();
            }
        }
        return readAcl.toString();
    }

    public static String getReadAcl(Connection conn, String id)
            throws SQLException {
        String localReadAcl;
        StringBuffer readAcl = new StringBuffer();

        PreparedStatement ps1 = null;
        PreparedStatement ps2 = null;
        try {
            ps1 = conn.prepareStatement("SELECT PARENTID FROM HIERARCHY WHERE ID = ?;");
            boolean first = true;
            do {
                // local acl
                localReadAcl = getLocalReadAcl(conn, id);
                if (localReadAcl != null && (localReadAcl.length() > 0)) {
                    if (readAcl.length() == 0) {
                        readAcl.append(localReadAcl);
                    } else {
                        readAcl.append(',' + localReadAcl);
                    }
                }
                // get parent
                ps1.setObject(1, id);
                ResultSet rs = ps1.executeQuery();
                String newId;
                if (rs.next()) {
                    newId = (String) rs.getObject(1);
                    if (rs.wasNull()) {
                        newId = null;
                    }
                } else {
                    // no such id
                    newId = null;
                }
                if (first && newId == null) {
                    // there is no parent for the first level
                    // we may have a version on our hands, find the live doc
                    ps2 = conn.prepareStatement("SELECT VERSIONABLEID FROM VERSIONS WHERE ID = ?;");
                    ps2.setObject(1, id);
                    rs = ps2.executeQuery();
                    if (rs.next()) {
                        newId = (String) rs.getObject(1);
                        if (rs.wasNull()) {
                            newId = null;
                        }
                    } else {
                        // no such id
                        newId = null;
                    }
                }
                first = false;
                id = newId;
            } while (id != null);
        } finally {
            if (ps1 != null) {
                ps1.close();
            }
            if (ps2 != null) {
                ps2.close();
            }
        }
        return readAcl.toString();
    }

    public static ResultSet getReadAclsFor(Connection conn, String principals)
            throws SQLException {
        DatabaseMetaData meta = conn.getMetaData();
        SimpleResultSet result = new SimpleResultSet();
        result.addColumn("ID", Types.VARCHAR, 0, 0); // String id
        if (meta.getURL().startsWith("jdbc:columnlist:")) {
            // this is just to query the result set columns
            return result;
        }
        if (principals == null) {
            return result;
        }
        Set principalsList = split(principals);
        Set blackList = new HashSet();
        for (String user : principalsList) {
            blackList.add('-' + user);
        }
        // log.debug("getReadAclFor " + principals);
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = conn.prepareStatement("SELECT \"ID\", \"ACL\" FROM READ_ACLS");
            rs = ps.executeQuery();
            while (rs.next()) {
                String id = rs.getString(1);
                String[] acl = rs.getString(2).split(",");
                for (String ace : acl) {
                    // log.debug("ace: " + ace);
                    if (principalsList.contains(ace)) {
                        result.addRow(new Object[] { id });
                        // log.debug("allowed: " + id);
                    } else if (blackList.contains(ace)) {
                        // log.debug("deny: " + id);
                        break;
                    }
                }
            }
        } finally {
            if (rs != null) {
                rs.close();
            }
            if (ps != null) {
                ps.close();
            }
        }
        return result;
    }

    public static class LogAclsModified implements org.h2.api.Trigger,
            CloseListener {

        private String idName = "ID";

        private int idIndex;

        private int idType;

        /**
         * Trigger interface: initialization.
         */
        public void init(Connection conn, String schema, String triggerName,
                String table, boolean before, int opType) throws SQLException {
            ResultSet rs = null;
            try {
                DatabaseMetaData meta = conn.getMetaData();
                rs = meta.getColumns(null, schema, table, idName);
                if (!rs.next()) {
                    throw new SQLException("No id key for: " + schema + '.'
                            + table);
                }
                idType = rs.getInt("DATA_TYPE");
                idIndex = rs.getInt("ORDINAL_POSITION") - 1;
            } finally {
                if (rs != null) {
                    rs.close();
                }
            }
        }

        /**
         * Trigger interface.
         */
        public void fire(Connection conn, Object[] oldRow, Object[] newRow)
                throws SQLException {
            if (newRow != null) {
                PreparedStatement ps = null;
                try {
                    ps = conn.prepareStatement("INSERT INTO hierarchy_modified_acl VALUES(?, ?);");
                    ps.setString(2, "f");
                    if (oldRow != null) {
                        // update or delete
                        ps.setString(1, oldRow[idIndex].toString());
                    } else {
                        // insert
                        ps.setString(1, newRow[idIndex].toString());
                    }
                    ps.executeUpdate();
                } finally {
                    if (ps != null) {
                        ps.close();
                    }
                }
            }
        }

        public void close() throws SQLException {
        }

        public void remove() {
        }

    }

    public static class LogHierarchyModified implements org.h2.api.Trigger,
            CloseListener {
        private String idName = "ID";

        private int idIndex;

        private int idType;

        private String parentIdName = "PARENTID";

        private int parentIdIndex;

        /**
         * Trigger interface: initialization.
         */
        public void init(Connection conn, String schema, String triggerName,
                String table, boolean before, int opType) throws SQLException {
            ResultSet rs = null;
            try {
                DatabaseMetaData meta = conn.getMetaData();
                rs = meta.getColumns(null, schema, table, idName);
                if (!rs.next()) {
                    throw new SQLException("No id key for: " + schema + '.'
                            + table);
                }
                idType = rs.getInt("DATA_TYPE");
                idIndex = rs.getInt("ORDINAL_POSITION") - 1;
                rs.close();
                rs = meta.getColumns(null, schema, table, parentIdName);
                if (!rs.next()) {
                    throw new SQLException("No parentid for in " + schema + '.'
                            + table);
                }
                parentIdIndex = rs.getInt("ORDINAL_POSITION") - 1;
            } finally {
                if (rs != null) {
                    rs.close();
                }
            }

        }

        /**
         * Trigger interface.
         */
        public void fire(Connection conn, Object[] oldRow, Object[] newRow)
                throws SQLException {
            if (newRow != null) {
                PreparedStatement ps = null;
                try {
                    ps = conn.prepareStatement("INSERT INTO hierarchy_modified_acl VALUES(?, ?);");
                    ps.setString(1, newRow[idIndex].toString());
                    if (oldRow == null) {
                        // Insert
                        ps.setString(2, "t");
                        ps.executeUpdate();
                    } else if (oldRow[parentIdIndex] != newRow[parentIdIndex]) {
                        // Update with new parent
                        ps.setString(2, "f");
                        ps.executeUpdate();
                    }
                } finally {
                    if (ps != null) {
                        ps.close();
                    }
                }
            }
        public void close() throws SQLException {
        }

        public void remove() {
        }

    }

    public static ResultSet rebuildReadAcls(Connection conn)
            throws SQLException {
        SimpleResultSet result = new SimpleResultSet();
        PreparedStatement ps = null;
        try {
            ps = conn.prepareStatement("TRUNCATE TABLE hierarchy_read_acl;");
            ps.executeUpdate();
            ps = conn.prepareStatement("INSERT INTO hierarchy_read_acl" //
                    + "  SELECT id, nx_get_read_acl(id)"
                    + "  FROM (SELECT DISTINCT(id) AS id FROM hierarchy) AS uids;");
            ps.executeUpdate();
            ps = conn.prepareStatement("TRUNCATE TABLE read_acls;");
            ps.executeUpdate();
            // TODO: use md5 of the acl as key
            ps = conn.prepareStatement("INSERT INTO read_acls" //
                    + "  SELECT acl, acl" //
                    + "  FROM (SELECT DISTINCT(nx_get_read_acl(id)) AS acl" //
                    + "        FROM  (SELECT DISTINCT(id) AS id" //
                    + "               FROM acls) AS uids) AS read_acls_input;");
            ps.executeUpdate();
            ps = conn.prepareStatement("TRUNCATE TABLE hierarchy_modified_acl;");
            ps.executeUpdate();
        } finally {
            if (ps != null) {
                ps.close();
            }
        }
        return result;
    }

    public static ResultSet updateReadAcls(Connection conn) throws SQLException {
        SimpleResultSet result = new SimpleResultSet();
        PreparedStatement ps = null;
        int rowCount = 0;
        try {
            ps = conn.prepareStatement("TRUNCATE TABLE read_acls;");
            ps.executeUpdate();
            // TODO: use md5 of the acl as key
            ps = conn.prepareStatement("INSERT INTO read_acls" //
                    + " SELECT acl, acl" //
                    + " FROM (SELECT DISTINCT(nx_get_read_acl(id)) AS acl" //
                    + "       FROM  (SELECT DISTINCT(id) AS id" //
                    + "              FROM acls) AS uids) AS read_acls_input;");
            ps.executeUpdate();

            // New hierarchy_read_acl entry
            ps = conn.prepareStatement("INSERT INTO hierarchy_read_acl" //
                    + " SELECT id, nx_get_read_acl(id)" //
                    + " FROM (SELECT DISTINCT(id) AS id" //
                    + "   FROM hierarchy_modified_acl" //
                    + "   WHERE is_new AND" //
                    + "     EXISTS (SELECT 1 FROM hierarchy WHERE hierarchy_modified_acl.id=hierarchy.id)) AS uids;");
            rowCount = ps.executeUpdate();
            ps = conn.prepareStatement("DELETE FROM hierarchy_modified_acl WHERE is_new;");
            ps.executeUpdate();
            // Update hierarchy_read_acl entry
            // Mark acl that need to be updated (set to NULL)
            ps = conn.prepareStatement("UPDATE hierarchy_read_acl SET acl_id = NULL WHERE id IN (" //
                    + " SELECT DISTINCT(id) AS id FROM hierarchy_modified_acl WHERE NOT is_new);");
            rowCount = ps.executeUpdate();
            ps = conn.prepareStatement("DELETE FROM hierarchy_modified_acl WHERE NOT is_new;");
            ps.executeUpdate();
            ps = conn.prepareStatement("UPDATE hierarchy_read_acl SET acl_id = NULL WHERE id IN (" //
                    + " SELECT h.id" //
                    + " FROM hierarchy AS h" //
                    + " LEFT JOIN hierarchy_read_acl AS r ON h.id = r.id" //
                    + " WHERE r.acl_id IS NOT NULL" //
                    + " AND h.parentid IN (SELECT id FROM hierarchy_read_acl WHERE acl_id IS NULL));");
            // Mark all childrens
            do {
                rowCount = ps.executeUpdate();
            } while (rowCount > 0);
            // Update hierarchy_read_acl acl_ids
            // TODO use the md5 for acl_id
            ps = conn.prepareStatement("UPDATE hierarchy_read_acl SET acl_id = nx_get_read_acl(id) WHERE acl_id IS NULL;");
            ps.executeUpdate();
        } finally {
            if (ps != null) {
                ps.close();
            }
        }

        return result;
    }

}
File
H2Functions.java
Developer's decision
Concatenation
Kind of conflict
Class declaration
Comment
Method declaration
Chunk
Conflicting content
                        "CREATE ALIAS IF NOT EXISTS NXFT_INIT FOR \"%s.init\"; "
                                + "CALL NXFT_INIT()", h2Fulltext)));

<<<<<<< HEAD
        FulltextInfo fti = model.getFulltextInfo();
        for (String indexName : fti.indexNames) {
            String analyzer = fti.indexAnalyzer.get(indexName);
            if (analyzer == null) {
                analyzer = DEFAULT_FULLTEXT_ANALYZER;
            }
            String fullIndexName = String.format("PUBLIC_%s_%s", ft.getName(),
                    indexName);
            String suffix = indexName.equals(Model.FULLTEXT_DEFAULT_INDEX) ? ""
                    : '_' + indexName;
            Column ftst = ft.getColumn(model.FULLTEXT_SIMPLETEXT_KEY + suffix);
            Column ftbt = ft.getColumn(model.FULLTEXT_BINARYTEXT_KEY + suffix);
            statements.add(new ConditionalStatement(
                    false, // late
                    Boolean.FALSE, // no drop
                    null, //
                    null, //
                    String.format(
                            "CALL NXFT_CREATE_INDEX('%s', 'PUBLIC', '%s', ('%s', '%s'), '%s')",
                            fullIndexName, ft.getName(),
                            ftst.getPhysicalName(), ftbt.getPhysicalName(),
                            analyzer)));
        }

        // read acls ----------------------------------------------------------
        // table to store canonical read acls
        statements.add(new ConditionalStatement( //
                false, // late
                Boolean.FALSE, // no drop
                null, //
                null, //
                "CREATE TABLE IF NOT EXISTS read_acls (" //
                        + "  id character varying(4096) PRIMARY KEY," //
                        + "  acl character varying(4096));")); //
        // table to maintain a read acl for each hierarchy entry
        statements.add(new ConditionalStatement(
                false, // late
                Boolean.FALSE, // no drop
                null, //
                null, //
                "CREATE TABLE IF NOT EXISTS hierarchy_read_acl (" //
                        + "  id character varying(36) PRIMARY KEY," //
                        + "  acl_id character varying(4096)," //
                        + "  CONSTRAINT hierarchy_read_acl_id_fk FOREIGN KEY (id) REFERENCES hierarchy(id) ON DELETE CASCADE" //
                        + ");"));
        // Add index
        statements.add(new ConditionalStatement(
                false, // late
                Boolean.FALSE, // no drop
                null, //
                null, //
                "CREATE INDEX IF NOT EXISTS hierarchy_read_acl_acl_id_idx ON hierarchy_read_acl(acl_id);"));
        // Log hierarchy with updated read acl
        statements.add(new ConditionalStatement(
                false, // late
                Boolean.FALSE, // no drop
                null, //
                null, //
                "CREATE TABLE IF NOT EXISTS hierarchy_modified_acl ("
                        + "  id character varying(36)," //
                        + "  is_new boolean" //
                        + ");"));
        statements.add(makeFunction("nx_get_read_acl", //
                "getReadAcl"));
        statements.add(makeFunction("nx_get_read_acls_for", //
                "getReadAclsFor"));
        statements.add(makeFunction("nx_rebuild_read_acls", //
                "rebuildReadAcls"));
        statements.add(makeFunction("nx_update_read_acls", //
                "updateReadAcls"));
        statements.add(new ConditionalStatement(
                false, // late
                Boolean.TRUE, // do a drop
                null, //
                "DROP TRIGGER IF EXISTS nx_trig_acls_modified;",
                "CREATE TRIGGER nx_trig_acls_modified\n" //
                        + "  AFTER INSERT, UPDATE, DELETE ON acls\n" //
                        + "  FOR EACH ROW CALL \""+ h2Functions +"$LogAclsModified\";"));
        statements.add(new ConditionalStatement(
                false, // late
                Boolean.TRUE, // do a drop
                null, //
                "DROP TRIGGER IF EXISTS nx_trig_hierarchy_modified;",
                "CREATE TRIGGER nx_trig_hierarchy_modified\n" //
                        + "  AFTER INSERT, UPDATE ON hierarchy\n" //
                        + "  FOR EACH ROW CALL \""+ h2Functions +"$LogHierarchyModified\";"));
        // build the read acls if empty, this takes care of the upgrade
        statements.add(new ConditionalStatement(
                false, // late
                null, // perform a check
                "SELECT 1 WHERE NOT EXISTS(SELECT 1 FROM read_acls LIMIT 1);",
                "SELECT * FROM nx_rebuild_read_acls();", //
                "SELECT 1;"));
=======
        statements.add(makeTrigger("NX_TRIG_DESC", ht.getQuotedName(),
                h2TrigDesc));
>>>>>>> f5ac6c074337f5be4ab732b46312fe57d3803bd6

        return statements;
    }
Solution content
                        "CREATE ALIAS IF NOT EXISTS NXFT_INIT FOR \"%s.init\"; "
                                + "CALL NXFT_INIT()", h2Fulltext)));

        statements.add(makeTrigger("NX_TRIG_DESC", ht.getQuotedName(),
                h2TrigDesc));

        // read acls ----------------------------------------------------------
        // table to store canonical read acls
        statements.add(new ConditionalStatement( //
                false, // late
                Boolean.FALSE, // no drop
                null, //
                null, //
                "CREATE TABLE IF NOT EXISTS read_acls (" //
                        + "  id character varying(4096) PRIMARY KEY," //
                        + "  acl character varying(4096));")); //
        // table to maintain a read acl for each hierarchy entry
        statements.add(new ConditionalStatement(
                false, // late
                Boolean.FALSE, // no drop
                null, //
                null, //
                "CREATE TABLE IF NOT EXISTS hierarchy_read_acl (" //
                        + "  id character varying(36) PRIMARY KEY," //
                        + "  acl_id character varying(4096)," //
                        + "  CONSTRAINT hierarchy_read_acl_id_fk FOREIGN KEY (id) REFERENCES hierarchy(id) ON DELETE CASCADE" //
                        + ");"));
        // Add index
        statements.add(new ConditionalStatement(
                false, // late
                Boolean.FALSE, // no drop
                null, //
                null, //
                "CREATE INDEX IF NOT EXISTS hierarchy_read_acl_acl_id_idx ON hierarchy_read_acl(acl_id);"));
        // Log hierarchy with updated read acl
        statements.add(new ConditionalStatement(
                false, // late
                Boolean.FALSE, // no drop
                null, //
                null, //
                "CREATE TABLE IF NOT EXISTS hierarchy_modified_acl ("
                        + "  id character varying(36)," //
                        + "  is_new boolean" //
                        + ");"));
        statements.add(makeFunction("nx_get_read_acl", //
                "getReadAcl"));
        statements.add(makeFunction("nx_get_read_acls_for", //
                "getReadAclsFor"));
        statements.add(makeFunction("nx_rebuild_read_acls", //
                "rebuildReadAcls"));
        statements.add(makeFunction("nx_update_read_acls", //
                "updateReadAcls"));
        statements.add(new ConditionalStatement(
                false, // late
                Boolean.TRUE, // do a drop
                null, //
                "DROP TRIGGER IF EXISTS nx_trig_acls_modified;",
                "CREATE TRIGGER nx_trig_acls_modified\n" //
                        + "  AFTER INSERT, UPDATE, DELETE ON acls\n" //
                        + "  FOR EACH ROW CALL \""+ h2Functions +"$LogAclsModified\";"));
        statements.add(new ConditionalStatement(
                false, // late
                Boolean.TRUE, // do a drop
                null, //
                "DROP TRIGGER IF EXISTS nx_trig_hierarchy_modified;",
                "CREATE TRIGGER nx_trig_hierarchy_modified\n" //
                        + "  AFTER INSERT, UPDATE ON hierarchy\n" //
                        + "  FOR EACH ROW CALL \""+ h2Functions +"$LogHierarchyModified\";"));
        // build the read acls if empty, this takes care of the upgrade
        statements.add(new ConditionalStatement(
                false, // late
                null, // perform a check
                "SELECT 1 WHERE NOT EXISTS(SELECT 1 FROM read_acls LIMIT 1);",
                "SELECT * FROM nx_rebuild_read_acls();", //
                "SELECT 1;"));

        return statements;
    }
File
DialectH2.java
Developer's decision
Combination
Kind of conflict
Comment
For statement
Method invocation
Variable