/* 
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 java.sql;

import java.util.Properties;

/**
 * An interface to a JDBC driver.
 * <p>
 * The JDBC driver uses URLs to specify the location of specific data. URL
 * format typically takes the form " {@code xxxx:yyyy:SpecificData}", where "
 * {@code xxxx:yyyy}" is referred to as the <i>subprotocol</i> and is normally
 * the same for all of a particular driver. " {@code SpecificData}" is a string
 * which identifies the particular data source that the driver should use.
 * <p>
 * A driver needs to be registered with a {@link DriverManager}. It is
 * registered and instantiated by calling {@code Class.forName("DriverURL")}
 * with the URL string as argument.
 *
 * @see DriverManager
 */
public interface Driver {

    /**
     * Returns whether the driver thinks that it can open a connection to the
     * given URL.
     * 
     * @param url
     *            the URL to connect to.
     * @return {@code true} if the driver thinks that is can open a connection
     *         to the supplied URL, {@code false} otherwise. Typically, the
     *         driver will respond {@code true} if it thinks that it can handle
     *         the subprotocol specified by the driver.
     * @throws SQLException
     *          if a database error occurs.
     */
    public boolean acceptsURL(String url) throws SQLException;

    /**
     * Attempts to make a database connection to a data source specified by a
     * supplied URL.
     * 
     * @param url
     *            the URL to connect.
     * @param info
     *            some properties that should be used in establishing the
     *            connection. The properties consist of name/value pairs of
     *            strings. Normally, a connection to a database requires at
     *            least two properties - for {@code "user"} and {@code
     *            "password"} in order to pass authentication to the database.
     * @return the connection to the database.
     * @throws SQLException
     *             if a database error occurs.
     */
    public Connection connect(String url, Properties info) throws SQLException;

    /**
     * Gets the driver's major version number.
     * 
     * @return the major version number of the driver - typically starts at 1.
     */
    public int getMajorVersion();

    /**
     * Gets the driver's minor version number.
     * 
     * @return the minor version number of the driver - typically starts at 0.
     */
    public int getMinorVersion();

    /**
     * Gets information about possible properties for this driver.
     * <p>
     * This method is intended to provide a listing of possible properties that
     * the client of the driver must supply in order to establish a connection
     * to a database. Note that the returned array of properties may change
     * depending on the supplied list of property values.
     *
     * @param url
     *            the URL of the database. An application may call this method
     *            iteratively as the property list is built up - for example,
     *            when displaying a dialog to an end-user as part of the
     *            database login process.
     * @param info
     *            a set of tag/value pairs giving data that a user may be 
     *            prompted to provide in order to connect to the database.
     * @return an array of {@code DriverPropertyInfo} records which provide
     *         details on which additional properties are required (in addition
     *         to those supplied in the {@code info} parameter) in order to 
     *         connect to the database.
     * @throws SQLException
     *             if a database error occurs.
     */
    public DriverPropertyInfo[] getPropertyInfo(String url, Properties info)
            throws SQLException;

    /**
     * Reports whether this driver is a genuine JDBC CompliantTM driver. The
     * driver may only return {@code true} if it passes all the JDBC compliance
     * tests.
     * <p>
     * A driver may not be fully compliant if the underlying database has
     * limited functionality.
     *
     * @return {@code true} if the driver is fully JDBC compliant, {@code false}
     *         otherwise.
     */
    public boolean jdbcCompliant();

}
