<commit_before>/*
Copyright 2009-2014 <NAME>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/


package org.javalite.activejdbc;

import org.javalite.activejdbc.annotations.*;
import org.javalite.activejdbc.associations.*;
import org.javalite.activejdbc.cache.CacheManager;
import org.javalite.activejdbc.cache.QueryCache;
import org.javalite.activejdbc.statistics.StatisticsQueue;

import java.lang.reflect.Method;
import java.sql.DatabaseMetaData;
import java.util.*;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;

import org.javalite.common.Inflector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.javalite.common.Util.*;

/**
 * @author <NAME>
 */
public enum Registry {

    //our singleton!
    INSTANCE;

    private final static Logger logger = LoggerFactory.getLogger(Registry.class);

    private final MetaModels metaModels = new MetaModels();
    private final Map<Class, ModelRegistry> modelRegistries = new HashMap<Class, ModelRegistry>();
    private final Configuration configuration = new Configuration();
    private final StatisticsQueue statisticsQueue;
    private final Set<String> initedDbs = new HashSet<String>();

    private Registry() {
        statisticsQueue = configuration.collectStatistics()
                ? new StatisticsQueue(configuration.collectStatisticsOnHold())
                : null;
    }

    public boolean initialized() {
        return !initedDbs.isEmpty();
    }

    public static Registry instance() {
        return INSTANCE;
    }

    public StatisticsQueue getStatisticsQueue() {
        if (statisticsQueue == null) {
            throw new InitException("cannot collect statistics if this was not configured in activejdbc.properties file. Add 'collectStatistics = true' to it.");
        }
        return statisticsQueue;
    }

    public Configuration getConfiguration(){
        return configuration;
    }

    public static CacheManager cacheManager(){
        return QueryCache.instance().getCacheManager();
    }

    /**
     * Provides a MetaModel of a model representing a table.
     *
     * @param table name of table represented by this MetaModel.
     * @return MetaModel of a model representing a table.
     */
    public MetaModel getMetaModel(String table) {
        return metaModels.getMetaModel(table);
    }

    public MetaModel getMetaModel(Class<? extends Model> modelClass) {

        String dbName = MetaModel.getDbName(modelClass);
        init(dbName);

        return metaModels.getMetaModel(modelClass);
    }

    ModelRegistry modelRegistryOf(Class<? extends Model> modelClass) {
        ModelRegistry registry = modelRegistries.get(modelClass);
        if (registry == null) {
            registry = new ModelRegistry();
            modelRegistries.put(modelClass, registry);
        }
        return registry;
    }

     synchronized void init(String dbName) {

        if (initedDbs.contains(dbName)) {
            return;
        } else {
            initedDbs.add(dbName);
        }

        try {
            ModelFinder.findModels(dbName);
            Connection c = ConnectionsAccess.getConnection(dbName);
            if(c == null){
                throw new DBException("Failed to retrieve metadata from DB, connection: '" + dbName + "' is not available");
            }
            DatabaseMetaData databaseMetaData = c.getMetaData();
            //TODO: this is called databaseProductName, dbType or dbProduct throughtout the code; use unique name?
            String databaseProductName = c.getMetaData().getDatabaseProductName();
            List<Class<? extends Model>> modelClasses = ModelFinder.getModelsForDb(dbName);
            registerModels(dbName, modelClasses, databaseProductName);
            String[] tables = metaModels.getTableNames(dbName);

            for (String table : tables) {
                SortedMap<String, ColumnMetadata> metaParams = fetchMetaParams(databaseMetaData, databaseProductName, table);
                registerColumnMetadata(table, metaParams);
            }

            processOverrides(modelClasses);

            for (String table : tables) {
                discoverAssociationsFor(table, dbName);
            }
        } catch (Exception e) {
            initedDbs.remove(dbName);
            if (e instanceof InitException) {
                throw (InitException) e;
            }
            if (e instanceof DBException) {
                throw (DBException) e;
            } else {
                throw new InitException(e);
            }
        }
    }

    /**
     * Returns a hash keyed off a column name.
     *
     * @return
     * @throws java.sql.SQLException
     */
    private SortedMap<String, ColumnMetadata> fetchMetaParams(DatabaseMetaData databaseMetaData, String databaseProductName, String table) throws SQLException {

      /*
       * Valid table name format: tablename or schemaname.tablename
       */
        String[] vals = split(table, '.');
        String schema = null;
        String tableName;

        if(vals.length == 1) {
            tableName = vals[0];
        } else if (vals.length == 2) {
            schema = vals[0];
            tableName = vals[1];
            if (schema.length() == 0 || tableName.length() == 0) {
                throw new DBException("invalid table name : " + table);
            }
        } else {
            throw new DBException("invalid table name: " + table);
        }

        ResultSet rs = databaseMetaData.getColumns(null, schema, tableName, null);
        String dbProduct = databaseMetaData.getDatabaseProductName().toLowerCase();
        SortedMap<String, ColumnMetadata> columns = getColumns(rs, dbProduct);<commit_msg>#335 Util.split always returns nonempty chunks<commit_after>/*
Copyright 2009-2014 <NAME>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/


package org.javalite.activejdbc;

import org.javalite.activejdbc.annotations.*;
import org.javalite.activejdbc.associations.*;
import org.javalite.activejdbc.cache.CacheManager;
import org.javalite.activejdbc.cache.QueryCache;
import org.javalite.activejdbc.statistics.StatisticsQueue;

import java.lang.reflect.Method;
import java.sql.DatabaseMetaData;
import java.util.*;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;

import org.javalite.common.Inflector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.javalite.common.Util.*;

/**
 * @author <NAME>
 */
public enum Registry {

    //our singleton!
    INSTANCE;

    private final static Logger logger = LoggerFactory.getLogger(Registry.class);

    private final MetaModels metaModels = new MetaModels();
    private final Map<Class, ModelRegistry> modelRegistries = new HashMap<Class, ModelRegistry>();
    private final Configuration configuration = new Configuration();
    private final StatisticsQueue statisticsQueue;
    private final Set<String> initedDbs = new HashSet<String>();

    private Registry() {
        statisticsQueue = configuration.collectStatistics()
                ? new StatisticsQueue(configuration.collectStatisticsOnHold())
                : null;
    }

    public boolean initialized() {
        return !initedDbs.isEmpty();
    }

    public static Registry instance() {
        return INSTANCE;
    }

    public StatisticsQueue getStatisticsQueue() {
        if (statisticsQueue == null) {
            throw new InitException("cannot collect statistics if this was not configured in activejdbc.properties file. Add 'collectStatistics = true' to it.");
        }
        return statisticsQueue;
    }

    public Configuration getConfiguration(){
        return configuration;
    }

    public static CacheManager cacheManager(){
        return QueryCache.instance().getCacheManager();
    }

    /**
     * Provides a MetaModel of a model representing a table.
     *
     * @param table name of table represented by this MetaModel.
     * @return MetaModel of a model representing a table.
     */
    public MetaModel getMetaModel(String table) {
        return metaModels.getMetaModel(table);
    }

    public MetaModel getMetaModel(Class<? extends Model> modelClass) {

        String dbName = MetaModel.getDbName(modelClass);
        init(dbName);

        return metaModels.getMetaModel(modelClass);
    }

    ModelRegistry modelRegistryOf(Class<? extends Model> modelClass) {
        ModelRegistry registry = modelRegistries.get(modelClass);
        if (registry == null) {
            registry = new ModelRegistry();
            modelRegistries.put(modelClass, registry);
        }
        return registry;
    }

     synchronized void init(String dbName) {

        if (initedDbs.contains(dbName)) {
            return;
        } else {
            initedDbs.add(dbName);
        }

        try {
            ModelFinder.findModels(dbName);
            Connection c = ConnectionsAccess.getConnection(dbName);
            if(c == null){
                throw new DBException("Failed to retrieve metadata from DB, connection: '" + dbName + "' is not available");
            }
            DatabaseMetaData databaseMetaData = c.getMetaData();
            //TODO: this is called databaseProductName, dbType or dbProduct throughtout the code; use unique name?
            String databaseProductName = c.getMetaData().getDatabaseProductName();
            List<Class<? extends Model>> modelClasses = ModelFinder.getModelsForDb(dbName);
            registerModels(dbName, modelClasses, databaseProductName);
            String[] tables = metaModels.getTableNames(dbName);

            for (String table : tables) {
                SortedMap<String, ColumnMetadata> metaParams = fetchMetaParams(databaseMetaData, databaseProductName, table);
                registerColumnMetadata(table, metaParams);
            }

            processOverrides(modelClasses);

            for (String table : tables) {
                discoverAssociationsFor(table, dbName);
            }
        } catch (Exception e) {
            initedDbs.remove(dbName);
            if (e instanceof InitException) {
                throw (InitException) e;
            }
            if (e instanceof DBException) {
                throw (DBException) e;
            } else {
                throw new InitException(e);
            }
        }
    }

    /**
     * Returns a hash keyed off a column name.
     *
     * @return
     * @throws java.sql.SQLException
     */
    private SortedMap<String, ColumnMetadata> fetchMetaParams(DatabaseMetaData databaseMetaData, String databaseProductName, String table) throws SQLException {

      /*
       * Valid table name format: tablename or schemaname.tablename
       */
        String[] vals = split(table, '.');
        String schema = null;
        String tableName;

        if(vals.length == 1) {
            tableName = vals[0];
        } else if (vals.length == 2) {
            schema = vals[0];
            tableName = vals[1];
        } else {
            throw new DBException("invalid table name: " + table);
        }

        ResultSet rs = databaseMetaData.getColumns(null, schema, tableName, null);
        String dbProduct = databaseMetaData.getDatabaseProductName().toLowerCase();
        SortedMap<String, ColumnMetadata> columns = getColumns(rs, dbProduct);
{'fraction_non_alphanumeric': 0.08853233425639355, 'fraction_numerical': 0.00350219905522072, 'mean_word_length': 2.6328402366863903, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2559621', 'n_tokens_mistral': 3179, 'n_tokens_neox': 3091, 'n_words': 909}