001/*
002 * PermissionsEx
003 * Copyright (C) zml and PermissionsEx contributors
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *    http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package ca.stellardrift.permissionsex.datastore.sql.dao;
018
019import ca.stellardrift.permissionsex.datastore.sql.SqlDao;
020import org.checkerframework.checker.nullness.qual.Nullable;
021
022import java.sql.PreparedStatement;
023import java.sql.ResultSet;
024import java.sql.SQLException;
025import java.sql.Types;
026import java.util.regex.Matcher;
027import java.util.regex.Pattern;
028
029/**
030 * DAO covering legacy operations. Some things in here might be mildly weird because
031 * they have to handle bridging between two models of working with the database.
032 */
033public class LegacyDao {
034    public static final LegacyDao INSTANCE = new LegacyDao();
035    private static final Pattern TABLE_PATTERN = Pattern.compile("\\{([^}]+)}");
036
037    protected LegacyDao() {
038    }
039
040    public String getSelectEntitiesQuery() {
041        return "SELECT (`name`, `type`) FROM {permissions_entity}";
042    }
043
044    public String getSelectOptionsQuery() {
045        return "SELECT `permission`, `value`, `world` FROM `{permissions}` WHERE `name` = ? AND `type` = ? AND LENGTH(`value`) > 0";
046    }
047
048    public String getSelectOptionQuery() {
049        return "SELECT `value` FROM `{permissions}` WHERE `name` = ? AND `type` = ? AND `permission` = ? AND `world` = ? AND LENGTH(`value`) > 0";
050    }
051
052    public String getInsertOptionQuery() {
053        return "INSERT INTO `{permissions}` (`name`, `type`, `permission`, `world`, `value`) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)";
054    }
055
056    public String getSelectPermissionQuery() {
057        return "SELECT `permission`, `world` FROM `{permissions}` WHERE `name` = ? AND `type` = ? AND LENGTH(`value`) = 0 ORDER BY `id` DESC";
058    }
059
060    public String getSelectParentsQuery() {
061        return "SELECT `id`, `parent`, `world` FROM `{}permissions_inheritance_old` WHERE `child` = ? AND `type` = ? ORDER BY `world`, `id` DESC";
062    }
063
064    @SuppressWarnings("JdkObsolete") // StringBuilder methods on Matcher were only added in JDK 9
065    public PreparedStatement prepareStatement(SqlDao dao, String query) throws SQLException {
066        StringBuffer ret = new StringBuffer();
067        Matcher m = TABLE_PATTERN.matcher(query);
068        while (m.find()) {
069            m.appendReplacement(ret, dao.getDataStore().getTableName(m.group(1), true));
070        }
071        m.appendTail(ret);
072
073        return dao.prepareStatement(ret.toString());
074    }
075
076    public boolean hasTable(SqlDao dao, String table) throws SQLException {
077        return dao.getConnection().getMetaData().getTables(null, null, dao.getDataStore().getTableName(table, true).toUpperCase(), null).next(); // Upper-case for H2
078    }
079
080    public void renameTable(SqlDao dao, String oldName, String newName) throws SQLException {
081        final String expandedOld = dao.getDataStore().getTableName(oldName, true);
082        final String expandedNew = dao.getDataStore().getTableName(newName, false);
083        try (PreparedStatement stmt = prepareStatement(dao, "ALTER TABLE `" + expandedOld + "` RENAME `" + expandedNew + "`")) {
084        /*try (PreparedStatement stmt = prepareStatement(dao, dao.getRenameTableQuery())) {
085            stmt.setString(1, expandedOld);
086            stmt.setString(2, expandedNew);*/
087            stmt.executeUpdate();
088        }
089    }
090
091    public @Nullable String getOption(SqlDao dao, String name, LegacyMigration.Type type, final @Nullable String world, String option) throws SQLException {
092        try (PreparedStatement stmt = prepareStatement(dao, getSelectOptionQuery())) {
093            stmt.setString(1, name);
094            stmt.setInt(2, type.ordinal());
095            stmt.setString(3, option);
096            if (world == null) {
097                stmt.setNull(4, Types.VARCHAR);
098            } else {
099                stmt.setString(4, world);
100            }
101
102            ResultSet rs = stmt.executeQuery();
103            if (rs.next()) {
104                return rs.getString(1);
105            } else {
106                return null;
107            }
108        }
109    }
110}