<commit_before>/*
 *    GeoTools - The Open Source Java GIS Toolkit
 *    http://geotools.org
 *
 *    (C) 2002-2016, Open Source Geospatial Foundation (OSGeo)
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License as published by the Free Software Foundation;
 *    version 2.1 of the License.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 */
package org.geotools.jdbc;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.geotools.util.logging.Logging;

/**
 * Looks up primary key information in a metadata table provided by the user.
 * <p>
 * The table schema will contain:
 * <ul>
 * <li>table_schema (varchar): schema name</li>
 * <li>table_name (varchar): table name</li>
 * <li>pk_column (varchar): column name</li>
 * <li>pk_column_idx (integer): column index if pk is multicolumn (nullable)</li>
 * <li>pk_policy (varchar): pk assignment policy: "assigned", "sequence", "autogenerated"</li>
 * <li>pk_sequence (varchar): full name of the sequence to be used to generate the next value, if
 * any</li>
 * </ul>
 * 
 * By default the table is named 'GT_PK_METADATA'.
 * 
 * @see #DEFAULT_TABLE
 * @author <NAME> - OpenGeo
 * 
 *
 *
 * @source $URL$
 */
public class MetadataTablePrimaryKeyFinder extends PrimaryKeyFinder {
    protected static final Logger LOGGER = Logging.getLogger(MetadataTablePrimaryKeyFinder.class);

    /**
     * The default metadata table name: {@value}.
     */
    public static final String DEFAULT_TABLE = "GT_PK_METADATA";
    
    volatile Boolean metadataTableExists = null; 

    /**
     * Known policies pk column treatment policies.
     */
    enum Policy {
        assigned, sequence, autogenerated
    };

    /**
     * The schema that will contain the metadata table.
     */
    String tableSchema;

    /**
     * The table that will contain the metadata information.
     */
    String tableName = DEFAULT_TABLE;

    /**
     * The schema containing the table schema
     */
    public String getTableSchema() {
        return tableSchema;
    }

    public void setTableSchema(String tableSchema) {
        this.tableSchema = tableSchema;
        this.metadataTableExists = null;
    }

    /**
     * The metadata table name, defaults to {@code GT_PK_METADATA} if not specified.
     * 
     * @see #DEFAULT_TABLE
     */
    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
        this.metadataTableExists = null;
    }

    @Override
    public PrimaryKey getPrimaryKey(JDBCDataStore store, String schema, String table, Connection cx)
            throws SQLException {
        ResultSet rs = null;
        PreparedStatement st = null;
        
        String metadataSchema = getMetadataSchema(store);
        
        try {
            // first off, make sure the metadata table is there (we'll also
            // catch errors later but log them at a higher level in case the table
            // is there but does not have the required structure). We just don't want
            // to fill the logs of people not using the metadata table with errors 
            if(metadataTableExists == null) {
                synchronized (this) {
                    if(metadataTableExists == null) {
                        try {
                            
                            StringBuffer sb = new StringBuffer();
                            sb.append("SELECT * FROM ");
                            if (metadataSchema != null) {
                                sb.append(metadataSchema);
                                sb.append(".");
                            }
                            sb.append(tableName).append(" WHERE 1 = 0");
                            st = cx.prepareStatement(sb.toString());
                            rs = st.executeQuery();
                            metadataTableExists = true;
                        } catch(Exception e) {
                            // clean up the transaction status in case we are in auto-commit mode
                            if (e instanceof SQLException && !cx.getAutoCommit()) {
                                cx.rollback();
                            }
                            metadataTableExists = false;
                        } finally {
                            store.closeSafe(rs);
                            store.closeSafe(st);
                        }
                    }
                }
            }
            if(!metadataTableExists) {
                return null;
            }
            
            // build query against the metadata table
            List<String> parameters = new ArrayList<String>();
            StringBuffer sb = new StringBuffer();
            sb.append("SELECT * FROM ");
            if (metadataSchema != null) {
                sb.append(metadataSchema);
                sb.append(".");
            }
            sb.append(tableName);
            sb.append(" WHERE ");
            if (schema != null) {
                sb.append("table_schema = ? AND ");
                parameters.add(schema);
            }
            sb.append("table_name = ?");
            parameters.add(table);
            sb.append(" ORDER BY ");
            sb.append("pk_column_idx");
            sb.append(" ASC");
            String sql = sb.toString();
            LOGGER.log(Level.FINE, "Reading metadata table metadata: {0} [ parameters = {1} ]", new Object[] { sql, parameters });

            // extract information column by column
            DatabaseMetaData metaData = cx.getMetaData();
            st = cx.prepareStatement(sql);
            for (int i = 0; i < parameters.size(); i++) {
                st.setString(i+1, parameters.get(i));
            }
            rs = st.executeQuery();

            List<PrimaryKeyColumn> columns = new ArrayList<PrimaryKeyColumn>();
            Set<String> colNames = null;
            while (rs.next()) {
                String colName = rs.getString("pk_column");
                String policyStr = rs.getString("pk_policy");
                String sequence = rs.getString("pk_sequence");
                
                // check the column name is known
                if(colNames == null) {
                    colNames = getColumnNames(store, metaData, schema, table);
                }
                if(!colNames.contains(colName)) {
                    LOGGER.warning("Unknown column " + colName + " in table " + table);
                    return null;
                }
                    

                Policy policy = Policy.assigned;
                if (policyStr != null) {
                    try {
                        policy = Policy.valueOf(policyStr.toLowerCase());
                    } catch (IllegalArgumentException e) {
                        LOGGER.warning("Invalid policy value " + policyStr + ", valid values are"
                                + Arrays.asList(Policy.values()));
                        return null;
                    }
                }

                Class columnType = store.getColumnType(metaData, schema, table, colName);

                if (policy == Policy.assigned) {
                    columns.add(new NonIncrementingPrimaryKeyColumn(colName, columnType));
                } else if (policy == Policy.autogenerated) {
                    columns.add(new AutoGeneratedPrimaryKeyColumn(colName, columnType));
                } else if (policy == policy.sequence) {
                    columns.add(new SequencedPrimaryKeyColumn(colName, columnType, sequence));
                }
            }
            
            // see if we accumulated any info about this table
            if(columns.size() > 0)
                return new PrimaryKey(table, columns);
            else
                return null;
        } catch (SQLException e) {
            LOGGER.log(Level.WARNING, "Errors occurred accessing the primary key metadata table ",
                    e);
            return null;
        } finally {
            store.closeSafe(rs);
            store.closeSafe(st);
        }
    }

    Set<String> getColumnNames(JDBCDataStore store, DatabaseMetaData metaData, String schema,
                               String table) throws SQLException {
        ResultSet rs = null;
        Set<String> result = new HashSet<String>();
        try {
            rs = metaData.getColumns(null, store.escapeNamePattern(metaData, schema),
                    store.escapeNamePattern(metaData, table), null);
            while(rs.next()) {
                result.add(rs.getString("COLUMN_NAME"));
            }
        } finally {
            rs.close();
        }
        
        return result;
    }
    
    String getMetadataSchema(JDBCDataStore store) {
        if(tableSchema != null)
            return tableSchema;
        
        return store.getDatabaseSchema();
    }

}
<commit_msg>Use encodeSchemaName(...) while looking up GT_PK_METADATA<commit_after>/*
 *    GeoTools - The Open Source Java GIS Toolkit
 *    http://geotools.org
 *
 *    (C) 2002-2016, Open Source Geospatial Foundation (OSGeo)
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License as published by the Free Software Foundation;
 *    version 2.1 of the License.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 */
package org.geotools.jdbc;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.geotools.util.logging.Logging;

/**
 * Looks up primary key information in a metadata table provided by the user.
 * <p>
 * The table schema will contain:
 * <ul>
 * <li>table_schema (varchar): schema name</li>
 * <li>table_name (varchar): table name</li>
 * <li>pk_column (varchar): column name</li>
 * <li>pk_column_idx (integer): column index if pk is multicolumn (nullable)</li>
 * <li>pk_policy (varchar): pk assignment policy: "assigned", "sequence", "autogenerated"</li>
 * <li>pk_sequence (varchar): full name of the sequence to be used to generate the next value, if
 * any</li>
 * </ul>
 * 
 * By default the table is named 'GT_PK_METADATA'.
 * 
 * @see #DEFAULT_TABLE
 * @author <NAME> - OpenGeo
 * 
 *
 *
 * @source $URL$
 */
public class MetadataTablePrimaryKeyFinder extends PrimaryKeyFinder {
    protected static final Logger LOGGER = Logging.getLogger(MetadataTablePrimaryKeyFinder.class);

    /**
     * The default metadata table name: {@value}.
     */
    public static final String DEFAULT_TABLE = "GT_PK_METADATA";
    
    volatile Boolean metadataTableExists = null; 

    /**
     * Known policies pk column treatment policies.
     */
    enum Policy {
        assigned, sequence, autogenerated
    };

    /**
     * The schema that will contain the metadata table.
     */
    String tableSchema;

    /**
     * The table that will contain the metadata information.
     */
    String tableName = DEFAULT_TABLE;

    /**
     * The schema containing the table schema
     */
    public String getTableSchema() {
        return tableSchema;
    }

    public void setTableSchema(String tableSchema) {
        this.tableSchema = tableSchema;
        this.metadataTableExists = null;
    }

    /**
     * The metadata table name, defaults to {@code GT_PK_METADATA} if not specified.
     * 
     * @see #DEFAULT_TABLE
     */
    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
        this.metadataTableExists = null;
    }

    @Override
    public PrimaryKey getPrimaryKey(JDBCDataStore store, String schema, String table, Connection cx)
            throws SQLException {
        ResultSet rs = null;
        PreparedStatement st = null;
        
        String metadataSchema = getMetadataSchema(store);
        
        try {
            // first off, make sure the metadata table is there (we'll also
            // catch errors later but log them at a higher level in case the table
            // is there but does not have the required structure). We just don't want
            // to fill the logs of people not using the metadata table with errors 
            if(metadataTableExists == null) {
                synchronized (this) {
                    if(metadataTableExists == null) {
                        try {
                            
                            StringBuffer sb = new StringBuffer();
                            sb.append("SELECT * FROM ");
                            if (metadataSchema != null) {
                                store.getSQLDialect().encodeSchemaName(metadataSchema, sb);
                                sb.append(".");
                            }
                            sb.append(tableName).append(" WHERE 1 = 0");
                            st = cx.prepareStatement(sb.toString());
                            rs = st.executeQuery();
                            metadataTableExists = true;
                        } catch(Exception e) {
                            // clean up the transaction status in case we are in auto-commit mode
                            if (e instanceof SQLException && !cx.getAutoCommit()) {
                                cx.rollback();
                            }
                            metadataTableExists = false;
                        } finally {
                            store.closeSafe(rs);
                            store.closeSafe(st);
                        }
                    }
                }
            }
            if(!metadataTableExists) {
                return null;
            }
            
            // build query against the metadata table
            List<String> parameters = new ArrayList<String>();
            StringBuffer sb = new StringBuffer();
            sb.append("SELECT * FROM ");
            if (metadataSchema != null) {
                store.getSQLDialect().encodeSchemaName(metadataSchema, sb);
                sb.append(".");
            }
            sb.append(tableName);
            sb.append(" WHERE ");
            if (schema != null) {
                sb.append("table_schema = ? AND ");
                parameters.add(schema);
            }
            sb.append("table_name = ?");
            parameters.add(table);
            sb.append(" ORDER BY ");
            sb.append("pk_column_idx");
            sb.append(" ASC");
            String sql = sb.toString();
            LOGGER.log(Level.FINE, "Reading metadata table metadata: {0} [ parameters = {1} ]", new Object[] { sql, parameters });

            // extract information column by column
            DatabaseMetaData metaData = cx.getMetaData();
            st = cx.prepareStatement(sql);
            for (int i = 0; i < parameters.size(); i++) {
                st.setString(i+1, parameters.get(i));
            }
            rs = st.executeQuery();

            List<PrimaryKeyColumn> columns = new ArrayList<PrimaryKeyColumn>();
            Set<String> colNames = null;
            while (rs.next()) {
                String colName = rs.getString("pk_column");
                String policyStr = rs.getString("pk_policy");
                String sequence = rs.getString("pk_sequence");
                
                // check the column name is known
                if(colNames == null) {
                    colNames = getColumnNames(store, metaData, schema, table);
                }
                if(!colNames.contains(colName)) {
                    LOGGER.warning("Unknown column " + colName + " in table " + table);
                    return null;
                }
                    

                Policy policy = Policy.assigned;
                if (policyStr != null) {
                    try {
                        policy = Policy.valueOf(policyStr.toLowerCase());
                    } catch (IllegalArgumentException e) {
                        LOGGER.warning("Invalid policy value " + policyStr + ", valid values are"
                                + Arrays.asList(Policy.values()));
                        return null;
                    }
                }

                Class columnType = store.getColumnType(metaData, schema, table, colName);

                if (policy == Policy.assigned) {
                    columns.add(new NonIncrementingPrimaryKeyColumn(colName, columnType));
                } else if (policy == Policy.autogenerated) {
                    columns.add(new AutoGeneratedPrimaryKeyColumn(colName, columnType));
                } else if (policy == policy.sequence) {
                    columns.add(new SequencedPrimaryKeyColumn(colName, columnType, sequence));
                }
            }
            
            // see if we accumulated any info about this table
            if(columns.size() > 0)
                return new PrimaryKey(table, columns);
            else
                return null;
        } catch (SQLException e) {
            LOGGER.log(Level.WARNING, "Errors occurred accessing the primary key metadata table ",
                    e);
            return null;
        } finally {
            store.closeSafe(rs);
            store.closeSafe(st);
        }
    }

    Set<String> getColumnNames(JDBCDataStore store, DatabaseMetaData metaData, String schema,
                               String table) throws SQLException {
        ResultSet rs = null;
        Set<String> result = new HashSet<String>();
        try {
            rs = metaData.getColumns(null, store.escapeNamePattern(metaData, schema),
                    store.escapeNamePattern(metaData, table), null);
            while(rs.next()) {
                result.add(rs.getString("COLUMN_NAME"));
            }
        } finally {
            rs.close();
        }
        
        return result;
    }
    
    String getMetadataSchema(JDBCDataStore store) {
        if(tableSchema != null)
            return tableSchema;
        
        return store.getDatabaseSchema();
    }

}

{'fraction_non_alphanumeric': 0.09293193717277487, 'fraction_numerical': 0.0017801047120418849, 'mean_word_length': 1.6212433100041168, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5016450', 'n_tokens_mistral': 4797, 'n_tokens_neox': 4641, 'n_words': 1351}