<commit_before>/*
 * Copyright 2017 <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 com.axway.ats.rbv.clients;

import java.util.Date;
import java.util.Map;

import com.axway.ats.common.PublicAtsApi;
import com.axway.ats.common.dbaccess.DbKeys;
import com.axway.ats.common.dbaccess.OracleKeys;
import com.axway.ats.core.dbaccess.DbProvider;
import com.axway.ats.core.dbaccess.mssql.DbConnSQLServer;
import com.axway.ats.core.dbaccess.mssql.MssqlDbProvider;
import com.axway.ats.core.dbaccess.mysql.DbConnMySQL;
import com.axway.ats.core.dbaccess.mysql.MysqlDbProvider;
import com.axway.ats.core.dbaccess.oracle.DbConnOracle;
import com.axway.ats.core.dbaccess.oracle.OracleDbProvider;
import com.axway.ats.harness.config.TestBox;
import com.axway.ats.rbv.db.DbEncryptor;
import com.axway.ats.rbv.db.DbSearchTerm;
import com.axway.ats.rbv.db.DbStorage;
import com.axway.ats.rbv.db.rules.DbBinaryFieldRule;
import com.axway.ats.rbv.db.rules.DbBooleanFieldRule;
import com.axway.ats.rbv.db.rules.DbDateFieldRule;
import com.axway.ats.rbv.db.rules.DbDateFieldRule.MatchRelation;
import com.axway.ats.rbv.db.rules.DbFieldsRule;
import com.axway.ats.rbv.db.rules.DbNumericFieldRule;
import com.axway.ats.rbv.db.rules.DbStringFieldRule;
import com.axway.ats.rbv.executors.MetaExecutor;
import com.axway.ats.rbv.model.RbvException;

/**
 * Class used for base DB verifications
 * <p>Note that <code>check</code> methods add rules for match whereas actual rules
 * evaluation is done in one of the methods with <code>verify</code> prefix.</p>
  *
 * <br/><br/>
 * <b>User guide</b> pages related to this class:<br/>
 * <a href="https://axway.github.io/ats-framework/Common-test-verifications.html">RBV basics</a>
 * and
 * <a href="https://axway.github.io/ats-framework/Database-verifications.html">Database verification details</a>
 */
@PublicAtsApi
public class DbVerification extends VerificationSkeleton {

    private String        host;

    // A custom encryption provider interface
    protected DbEncryptor dbEncryptor;

    /**
     * Create a DB verification component using the data provided
     *
     * @param testBox           the test box
     * @param table             the table to search in
     *
     * @throws RbvException     thrown on error
     */
    @PublicAtsApi
    public DbVerification( TestBox testBox,
                           String table ) throws RbvException {

        this(testBox.getHost(),
             testBox.getDbPort(),
             testBox.getDbName(),
             testBox.getDbUser(),
             testBox.getDbPass(),
             new DbSearchTerm("SELECT * FROM " + table),
             testBox.getDbType(),
             testBox.getProperties());
    }

    /**
     * Create a DB verification component using the data provided
     *
     * @param testBox           the test box
     * @param searchTerm        the DbTerm which describes the SQL query used for retrieving the data
     *
     * @throws RbvException     thrown on error
     */
    @PublicAtsApi
    public DbVerification( TestBox testBox,
                           DbSearchTerm searchTerm ) throws RbvException {

        this(testBox.getHost(),
             testBox.getDbPort(),
             testBox.getDbName(),
             testBox.getDbUser(),
             testBox.getDbPass(),
             searchTerm,
             testBox.getDbType(),
             testBox.getProperties());
    }

    protected DbVerification( String host,
                              int port,
                              String database,
                              String user,
                              String password,
                              DbSearchTerm searchTerm,
                              String dbType,
                              Map<String, Object> customProperties ) throws RbvException {

        super();

        this.host = host;

        // avoid the possible NullPointerException
        if (dbType == null) {
            throw new RbvException("Database type not specified for host " + host);
        }
        DbProvider dbProvider;
        if (port != TestBox.DB_PORT_NOT_SPECIFIED) { // add custom port
            customProperties.put(DbKeys.PORT_KEY, new Integer(port));
        }
        switch (dbType) {
            case DbConnMySQL.DATABASE_TYPE:
                dbProvider = new MysqlDbProvider(new DbConnMySQL(host,
                                                                 database,
                                                                 user,
                                                                 password,
                                                                 customProperties));
                break;
            case DbConnSQLServer.DATABASE_TYPE:
                dbProvider = new MssqlDbProvider(new DbConnSQLServer(host,
                                                                     database,
                                                                     user,
                                                                     password,
                                                                     customProperties));
                break;
            case DbConnOracle.DATABASE_TYPE:
                Object dbSid = customProperties.get("dbsid");
                if (dbSid != null) {
                    customProperties.put(OracleKeys.SID_KEY, dbSid);
                }
                Object dbServiceName = customProperties.get("dbserviceName");
                if (dbServiceName != null) {
                    customProperties.put(OracleKeys.SERVICE_NAME_KEY, dbServiceName);
                }
                dbProvider = new OracleDbProvider(new DbConnOracle(host,
                                                                   database,
                                                                   user,
                                                                   password,
                                                                   customProperties));
                break;
            default:
                throw new RbvException("DB Provider '" + dbType + "' not supported!");
        }

        DbStorage storage = new DbStorage(dbProvider);
        folder = storage.getFolder(searchTerm);
        this.executor = new MetaExecutor();
    }

    DbVerification( DbSearchTerm searchTerm,
                    DbProvider dbProvider ) throws RbvException {

        super();

        DbStorage storage = new DbStorage(dbProvider);
        folder = storage.getFolder(searchTerm);
        this.executor = new MetaExecutor();
    }

    /**
     * Specify a custom encryption interface.
     * @param dbEncryptor<commit_msg>Add support for db verification of PostgreSQL databases<commit_after>/*
 * Copyright 2017 Axway Software
 * 
 * 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 com.axway.ats.rbv.clients;

import java.util.Date;
import java.util.Map;

import com.axway.ats.common.PublicAtsApi;
import com.axway.ats.common.dbaccess.DbKeys;
import com.axway.ats.common.dbaccess.OracleKeys;
import com.axway.ats.core.dbaccess.DbProvider;
import com.axway.ats.core.dbaccess.mssql.DbConnSQLServer;
import com.axway.ats.core.dbaccess.mssql.MssqlDbProvider;
import com.axway.ats.core.dbaccess.mysql.DbConnMySQL;
import com.axway.ats.core.dbaccess.mysql.MysqlDbProvider;
import com.axway.ats.core.dbaccess.oracle.DbConnOracle;
import com.axway.ats.core.dbaccess.oracle.OracleDbProvider;
import com.axway.ats.core.dbaccess.postgresql.DbConnPostgreSQL;
import com.axway.ats.core.dbaccess.postgresql.PostgreSqlProvider;
import com.axway.ats.harness.config.TestBox;
import com.axway.ats.rbv.db.DbEncryptor;
import com.axway.ats.rbv.db.DbSearchTerm;
import com.axway.ats.rbv.db.DbStorage;
import com.axway.ats.rbv.db.rules.DbBinaryFieldRule;
import com.axway.ats.rbv.db.rules.DbBooleanFieldRule;
import com.axway.ats.rbv.db.rules.DbDateFieldRule;
import com.axway.ats.rbv.db.rules.DbDateFieldRule.MatchRelation;
import com.axway.ats.rbv.db.rules.DbFieldsRule;
import com.axway.ats.rbv.db.rules.DbNumericFieldRule;
import com.axway.ats.rbv.db.rules.DbStringFieldRule;
import com.axway.ats.rbv.executors.MetaExecutor;
import com.axway.ats.rbv.model.RbvException;

/**
 * Class used for base DB verifications
 * <p>Note that <code>check</code> methods add rules for match whereas actual rules
 * evaluation is done in one of the methods with <code>verify</code> prefix.</p>
  *
 * <br/><br/>
 * <b>User guide</b> pages related to this class:<br/>
 * <a href="https://axway.github.io/ats-framework/Common-test-verifications.html">RBV basics</a>
 * and
 * <a href="https://axway.github.io/ats-framework/Database-verifications.html">Database verification details</a>
 */
@PublicAtsApi
public class DbVerification extends VerificationSkeleton {

    private String        host;

    // A custom encryption provider interface
    protected DbEncryptor dbEncryptor;

    /**
     * Create a DB verification component using the data provided
     *
     * @param testBox           the test box
     * @param table             the table to search in
     *
     * @throws RbvException     thrown on error
     */
    @PublicAtsApi
    public DbVerification( TestBox testBox,
                           String table ) throws RbvException {

        this(testBox.getHost(),
             testBox.getDbPort(),
             testBox.getDbName(),
             testBox.getDbUser(),
             testBox.getDbPass(),
             new DbSearchTerm("SELECT * FROM " + table),
             testBox.getDbType(),
             testBox.getProperties());
    }

    /**
     * Create a DB verification component using the data provided
     *
     * @param testBox           the test box
     * @param searchTerm        the DbTerm which describes the SQL query used for retrieving the data
     *
     * @throws RbvException     thrown on error
     */
    @PublicAtsApi
    public DbVerification( TestBox testBox,
                           DbSearchTerm searchTerm ) throws RbvException {

        this(testBox.getHost(),
             testBox.getDbPort(),
             testBox.getDbName(),
             testBox.getDbUser(),
             testBox.getDbPass(),
             searchTerm,
             testBox.getDbType(),
             testBox.getProperties());
    }

    protected DbVerification( String host,
                              int port,
                              String database,
                              String user,
                              String password,
                              DbSearchTerm searchTerm,
                              String dbType,
                              Map<String, Object> customProperties ) throws RbvException {

        super();

        this.host = host;

        // avoid the possible NullPointerException
        if (dbType == null) {
            throw new RbvException("Database type not specified for host " + host);
        }
        DbProvider dbProvider;
        if (port != TestBox.DB_PORT_NOT_SPECIFIED) { // add custom port
            customProperties.put(DbKeys.PORT_KEY, new Integer(port));
        }
        switch (dbType) {
            case DbConnMySQL.DATABASE_TYPE:
                dbProvider = new MysqlDbProvider(new DbConnMySQL(host,
                                                                 database,
                                                                 user,
                                                                 password,
                                                                 customProperties));
                break;
            case DbConnSQLServer.DATABASE_TYPE:
                dbProvider = new MssqlDbProvider(new DbConnSQLServer(host,
                                                                     database,
                                                                     user,
                                                                     password,
                                                                     customProperties));
                break;
            case DbConnOracle.DATABASE_TYPE:
                Object dbSid = customProperties.get("dbsid");
                if (dbSid != null) {
                    customProperties.put(OracleKeys.SID_KEY, dbSid);
                }
                Object dbServiceName = customProperties.get("dbserviceName");
                if (dbServiceName != null) {
                    customProperties.put(OracleKeys.SERVICE_NAME_KEY, dbServiceName);
                }
                dbProvider = new OracleDbProvider(new DbConnOracle(host,
                                                                   database,
                                                                   user,
                                                                   password,
                                                                   customProperties));
                break;
            case DbConnPostgreSQL.DATABASE_TYPE:
                dbProvider = new PostgreSqlProvider(new DbConnPostgreSQL(host, database, user, password));
                break;
            default:
                throw new RbvException("DB Provider '" + dbType + "' not supported!");
        }

        DbStorage storage = new DbStorage(dbProvider);
        folder = storage.getFolder(searchTerm);
        this.executor = new MetaExecutor();
    }

    DbVerification( DbSearchTerm searchTerm,
                    DbProvider dbProvider ) throws RbvException {

        super();

        DbStorage storage = new DbStorage(dbProvider);
        folder = storage.getFolder(searchTerm);
        this.executor = new MetaExecutor();
    }

    /**
     * Specify a custom encryption interface.
     * @param dbEncryptor
{'fraction_non_alphanumeric': 0.08202833706189411, 'fraction_numerical': 0.001084672225611823, 'mean_word_length': 1.6546697858556776, 'pattern_counts': {'":': 0, '<': 36, '<?xml version=': 0, '>': 36, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 58, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6078646', 'n_tokens_mistral': 3799, 'n_tokens_neox': 3639, 'n_words': 889}