/*
 * call-seq:
 *   OCI8::ConnectionPool.new(conn_min, conn_max, conn_incr, username = nil, password = nil, dbname = nil) -> connection pool
 *   OCI8::ConnectionPool.new(conn_min, conn_max, conn_incr, connect_string) -> connection pool
 *
 * Creates a connection pool.
 *
 * <i>conn_min</i> specifies the minimum number of connections in the
 * connection pool. Valid values are 0 and higher.
 *
 * <i>conn_max</i> specifies the maximum number of connections that
 * can be opened to the database. Once this value is reached, no more
 * connections are opened. Valid values are 1 and higher.
 *
 * <i>conn_incr</i> allows the application to set the next increment
 * for connections to be opened to the database if the current number
 * of connections are less than <i>conn_max</i>. Valid values are 0
 * and higher.
 *
 * <i>username</i> and <i>password</i> are required to establish an
 * implicit primary session. When both are nil, external
 * authentication is used.
 *
 * <i>dbname</i> specifies the database server to connect to.
 *
 * If the number of arguments is four, <i>username</i>,
 * <i>password</i> and <i>dbname</i> are extracted from the fourth
 * argument <i>connect_string</i>. The syntax is "username/password" or
 * "username/password@dbname".
 */
static VALUE oci8_cpool_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE conn_min;
    VALUE conn_max;
    VALUE conn_incr;
    VALUE username;
    VALUE password;
    VALUE dbname;
    oci8_cpool_t *cpool = DATA_PTR(self);
    OraText *pool_name;
    sb4 pool_name_len;
    sword rv;

    /* check arguments */
    rb_scan_args(argc, argv, "42", &conn_min, &conn_max, &conn_incr,
                 &username, &password, &dbname);
    Check_Type(conn_min, T_FIXNUM);
    Check_Type(conn_max, T_FIXNUM);
    Check_Type(conn_incr, T_FIXNUM);
    if (argc == 4) {
        VALUE mode;
        VALUE conn_str = username;

        OCI8SafeStringValue(conn_str);
        oci8_do_parse_connect_string(conn_str, &username, &password, &dbname, &mode);
        if (!NIL_P(mode)) {
            rb_raise(rb_eArgError, "invalid connect string \"%s\": Connection pooling doesn't support sysdba and sysoper privileges.", RSTRING_PTR(conn_str));
        }
    } else {
        if (!NIL_P(username)) {
            OCI8SafeStringValue(username);
        }
        if (!NIL_P(password)) {
            OCI8SafeStringValue(password);
        }
        if (!NIL_P(dbname)) {
            OCI8SafeStringValue(dbname);
        }
    }

    rv = OCIHandleAlloc(oci8_envhp, &cpool->base.hp.ptr, OCI_HTYPE_CPOOL, 0, NULL);
    if (rv != OCI_SUCCESS)
        oci8_env_raise(oci8_envhp, rv);
    cpool->base.type = OCI_HTYPE_CPOOL;

    oci_lc(OCIConnectionPoolCreate(oci8_envhp, oci8_errhp, cpool->base.hp.poolhp,
                                   &pool_name, &pool_name_len,
                                   NIL_P(dbname) ? NULL : RSTRING_ORATEXT(dbname),
                                   NIL_P(dbname) ? 0 : RSTRING_LEN(dbname),
                                   FIX2UINT(conn_min), FIX2UINT(conn_max),
                                   FIX2UINT(conn_incr),
                                   NIL_P(username) ? NULL : RSTRING_ORATEXT(username),
                                   NIL_P(username) ? 0 : RSTRING_LEN(username),
                                   NIL_P(password) ? NULL : RSTRING_ORATEXT(password),
                                   NIL_P(password) ? 0 : RSTRING_LEN(password),
                                   OCI_DEFAULT));
    cpool->pool_name = rb_str_new(TO_CHARPTR(pool_name), pool_name_len);
    rb_str_freeze(cpool->pool_name);
    return Qnil;
}
/*
 * call-seq:
 *   reinitialize(min, max, incr)
 *
 * Changes the the number of minimum connections, the number of
 * maximum connections and the connection increment parameter.
 */
static VALUE oci8_cpool_reinitialize(VALUE self, VALUE conn_min, VALUE conn_max, VALUE conn_incr)
{
    oci8_cpool_t *cpool = DATA_PTR(self);
    OraText *pool_name;
    sb4 pool_name_len;

    /* check arguments */
    Check_Type(conn_min, T_FIXNUM);
    Check_Type(conn_max, T_FIXNUM);
    Check_Type(conn_incr, T_FIXNUM);

    oci_lc(OCIConnectionPoolCreate(oci8_envhp, oci8_errhp, cpool->base.hp.poolhp,
                                   &pool_name, &pool_name_len, NULL, 0, 
                                   FIX2UINT(conn_min), FIX2UINT(conn_max),
                                   FIX2UINT(conn_incr),
                                   NULL, 0, NULL, 0, OCI_CPOOL_REINITIALIZE));
    return self;
}
Exemple #3
0
/* main */
int main(int argc, char* argv[])
{
	double start, total;
	sword status;

	total = get_time();

	printf("START\n");

	get_command_line_arguments(argc, argv);

	start = get_time();
	OCIEnvCreate(&envhp, OCI_THREADED | OCI_OBJECT, (dvoid *)0,  NULL, NULL, NULL, 0, (dvoid *)0);
	elapsed_time("OCIEnvCreate", start);

	start = get_time();
	OCIHandleAlloc((dvoid *) envhp, (dvoid **) &errhp, OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) 0);
	OCIHandleAlloc((dvoid *) envhp, (dvoid **) &poolhp, OCI_HTYPE_CPOOL, (size_t) 0, (dvoid **) 0);
	elapsed_time("OCIHandleAlloc", start);
 
	if (!useConnectionPool)
	{
		/* CONNECT DIRECTLY TO THE SERVER */
		start = get_time();
		status = OCILogon2(
			envhp,					// envhp        (IN) A pointer to the environment where the connection pool is to be created.
			errhp,					// errhp    (IN/OUT) An error handle you can pass to OCIErrorGet() for diagnostic information in the event of an error.
			&svchp,					// svchp    (IN/OUT) Address of an OCI service context pointer. This is filled with a server and session handle.
			username,				// username     (IN) The user name used to authenticate the session. Must be in the encoding specified by the charset parameter of a previous call to OCIEnvNlsCreate().
			olen(username),			// uname_len    (IN) The length of username, in number of bytes, regardless of the encoding.
			password,				// password     (IN) The user's password. For connection pooling, if this parameter is NULL then OCILogon2() assumes that the logon is for a proxy user. It implicitly creates a proxy connection in such a case, using the pool user to authenticate the proxy user. Must be in the encoding specified by the charset parameter of a previous call to OCIEnvNlsCreate().
			olen(password),			// passwd_len   (IN) The length of password, in number of bytes, regardless of the encoding.
			database,				// dbname       (IN) For the default case, this indicates the connect string to use to connect to the Oracle Database.
			olen(database),			// dbname_len   (IN) The length of dbname. For session pooling and connection pooling, this value is returned by the OCISessionPoolCreate() or OCIConnectionPoolCreate() call respectively.
			OCI_DEFAULT				// mode         (IN) The values accepted are: OCI_DEFAULT, OCI_LOGON2_CPOOL, OCI_LOGON2_SPOOL, OCI_LOGON2_STMTCACHE, OCI_LOGON2_PROXY
			);
		elapsed_time("OCILogon2 to the server", start);
		if (status)
		{
			checkerr(errhp, status);
			exit(1);
		}

		/* DISCONNECT */
		start = get_time();
		checkerr(errhp, OCILogoff((dvoid *) svchp, errhp));
		elapsed_time("OCILogoff from the server", start);
	}

	if (useConnectionPool)
	{
		/* CREATE THE CONNECTION POOL */
		start = get_time();
		status = OCIConnectionPoolCreate(
			envhp,					// envhp        (IN) A pointer to the environment where the connection pool is to be created.
			errhp,					// errhp    (IN/OUT) An error handle you can pass to OCIErrorGet() for diagnostic information in the event of an error.
			poolhp,					// poolhp       (IN) An allocated pool handle.
			&poolName,				// poolName    (OUT) The name of the connection pool connected to.
			&poolNameLen,			// poolNameLen (OUT) The length of the string pointed to by poolName.
			database,				// dblink       (IN) Specifies the database (server) to connect to.
			olen(database),			// dblinkLen    (IN) The length of the string pointed to by dblink.
			conMin,					// connMin      (IN) Specifies the minimum number of connections in the connection pool. Valid values are 0 and above.
			conMax,					// connMax      (IN) Specifies the maximum number of connections that can be opened to the database. Once this value is reached, no more connections are opened. Valid values are 1 and above.
			conIncr,				// connIncr     (IN) Allows the application to set the next increment for connections to be opened to the database if the current number of connections are less than connMax. Valid values are 0 and above.
			appusername,			// poolUsername (IN) Connection pooling requires an implicit primary session and this attribute provides a username for that session.
			olen(appusername),		// poolUserLen  (IN) The length of poolUsername.
			apppassword,			// poolPassword (IN) The password for the username poolUsername.
			olen(apppassword),		// poolPassLen  (IN) The length of poolPassword.
			OCI_DEFAULT				// mode         (IN) The modes supported are
			);
		elapsed_time("OCIConnectionPoolCreate", start);
		if (status)
		{
			checkerr(errhp, status);
			exit(1);
		}

		/* CONNECT USING THE CONNECTION POOL */
		start = get_time();
		status = OCILogon2(
			envhp,					// envhp        (IN) A pointer to the environment where the connection pool is to be created.
			errhp,					// errhp    (IN/OUT) An error handle you can pass to OCIErrorGet() for diagnostic information in the event of an error.
			&svchp,					// svchp    (IN/OUT) Address of an OCI service context pointer. This is filled with a server and session handle.
			username,				// username     (IN) The user name used to authenticate the session. Must be in the encoding specified by the charset parameter of a previous call to OCIEnvNlsCreate().
			olen(username),			// uname_len    (IN) The length of username, in number of bytes, regardless of the encoding.
			password,				// password     (IN) The user's password. For connection pooling, if this parameter is NULL then OCILogon2() assumes that the logon is for a proxy user. It implicitly creates a proxy connection in such a case, using the pool user to authenticate the proxy user. Must be in the encoding specified by the charset parameter of a previous call to OCIEnvNlsCreate().
			olen(password),			// passwd_len   (IN) The length of password, in number of bytes, regardless of the encoding.
			poolName,				// dbname       (IN) For the default case, this indicates the connect string to use to connect to the Oracle Database.
			poolNameLen,			// dbname_len   (IN) The length of dbname. For session pooling and connection pooling, this value is returned by the OCISessionPoolCreate() or OCIConnectionPoolCreate() call respectively.
			OCI_LOGON2_CPOOL		// mode         (IN) The values accepted are: OCI_DEFAULT, OCI_LOGON2_CPOOL, OCI_LOGON2_SPOOL, OCI_LOGON2_STMTCACHE, OCI_LOGON2_PROXY
			);
		elapsed_time("OCILogon2 using the connection pool", start);
		if (status)
		{
			checkerr(errhp, status);
			exit(1);
		}

		/* DISCONNECT */
		start = get_time();
		checkerr(errhp, OCILogoff((dvoid *) svchp, errhp));
		elapsed_time("OCILogoff from the connection pool", start);

		/* DESTROY THE CONNECTION POOL */
		start = get_time();
		checkerr(errhp, OCIConnectionPoolDestroy(poolhp, errhp, OCI_DEFAULT));
		elapsed_time("OCIConnectionPoolDestroy", start);
	}

	/* FREE HANDLES */  
	start = get_time();
	checkerr(errhp, OCIHandleFree((dvoid *)poolhp, OCI_HTYPE_CPOOL));
	checkerr(errhp, OCIHandleFree((dvoid *)errhp, OCI_HTYPE_ERROR));
	elapsed_time("OCIHandleFree", start);

	printf("END\n");
	elapsed_time("Total execution time", total);

	return 0;
}