root/odbc/birdstep.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _close_birdstep_link
  2. _free_birdstep_result
  3. PHP_MINIT_FUNCTION
  4. PHP_RINIT_FUNCTION
  5. PHP_MINFO_FUNCTION
  6. PHP_MSHUTDOWN_FUNCTION
  7. birdstep_add_conn
  8. birdstep_find_conn
  9. birdstep_del_conn
  10. birdstep_add_result
  11. birdstep_find_result
  12. birdstep_del_result
  13. PHP_FUNCTION
  14. PHP_FUNCTION
  15. PHP_FUNCTION
  16. PHP_FUNCTION
  17. PHP_FUNCTION
  18. PHP_FUNCTION
  19. PHP_FUNCTION
  20. PHP_FUNCTION
  21. PHP_FUNCTION
  22. PHP_FUNCTION
  23. PHP_FUNCTION
  24. PHP_FUNCTION

/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2013 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Nikolay P. Romanyuk <mag@redcom.ru>                         |
   +----------------------------------------------------------------------+
 */

/* $Id$ */

/*
 * TODO:
 * birdstep_fetch_into(),
 * Check all on real life apps.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"

#if WIN32
# include "config.w32.h"
# include "win95nt.h"
# ifdef PHP_EXPORTS
#  define PHPAPI __declspec(dllexport) 
# else
#  define PHPAPI __declspec(dllimport) 
# endif
#else
# include <php_config.h>
# define PHPAPI
# define THREAD_LS
#endif

#ifdef HAVE_BIRDSTEP
#include "php_birdstep.h"
#include "ext/standard/info.h"
#include "php_ini.h"

/* {{{ arginfo */
ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_connect, 0, 0, 3)
        ZEND_ARG_INFO(0, server)
        ZEND_ARG_INFO(0, user)
        ZEND_ARG_INFO(0, pass)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_close, 0, 0, 1)
        ZEND_ARG_INFO(0, id)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_exec, 0, 0, 2)
        ZEND_ARG_INFO(0, index)
        ZEND_ARG_INFO(0, exec_str)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_fetch, 0, 0, 1)
        ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_result, 0, 0, 2)
        ZEND_ARG_INFO(0, index)
        ZEND_ARG_INFO(0, col)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_freeresult, 0, 0, 1)
        ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_autocommit, 0, 0, 1)
        ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_off_autocommit, 0, 0, 1)
        ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_commit, 0, 0, 1)
        ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_rollback, 0, 0, 1)
        ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_fieldname, 0, 0, 2)
        ZEND_ARG_INFO(0, index)
        ZEND_ARG_INFO(0, col)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_birdstep_fieldnum, 0, 0, 1)
        ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()
/* }}} */

const zend_function_entry birdstep_functions[] = {
        PHP_FE(birdstep_connect,        arginfo_birdstep_connect)
        PHP_FE(birdstep_close,          arginfo_birdstep_close)
        PHP_FE(birdstep_exec,           arginfo_birdstep_exec)
        PHP_FE(birdstep_fetch,          arginfo_birdstep_fetch)
        PHP_FE(birdstep_result,         arginfo_birdstep_result)
        PHP_FE(birdstep_freeresult,     arginfo_birdstep_freeresult)
        PHP_FE(birdstep_autocommit,     arginfo_birdstep_autocommit)
        PHP_FE(birdstep_off_autocommit, arginfo_birdstep_off_autocommit)
        PHP_FE(birdstep_commit,         arginfo_birdstep_commit)
        PHP_FE(birdstep_rollback,       arginfo_birdstep_rollback)
        PHP_FE(birdstep_fieldnum,       arginfo_birdstep_fieldnum)
        PHP_FE(birdstep_fieldname,      arginfo_birdstep_fieldname)
/*
 * Temporary Function aliases until the next major upgrade to PHP.  
 * These should allow users to continue to use their current scripts, 
 * but should in reality warn the user that this functionality is 
 * deprecated.
 */
        PHP_FALIAS(velocis_connect,        birdstep_connect,        arginfo_birdstep_connect)
        PHP_FALIAS(velocis_close,          birdstep_close,          arginfo_birdstep_close)
        PHP_FALIAS(velocis_exec,           birdstep_exec,           arginfo_birdstep_exec)
        PHP_FALIAS(velocis_fetch,          birdstep_fetch,          arginfo_birdstep_fetch)
        PHP_FALIAS(velocis_result,         birdstep_result,         arginfo_birdstep_result)
        PHP_FALIAS(velocis_freeresult,     birdstep_freeresult,     arginfo_birdstep_freeresult)
        PHP_FALIAS(velocis_autocommit,     birdstep_autocommit,     arginfo_birdstep_autocommit)
        PHP_FALIAS(velocis_off_autocommit, birdstep_off_autocommit, arginfo_birdstep_off_autocommit)
        PHP_FALIAS(velocis_commit,         birdstep_commit,         arginfo_birdstep_commit)
        PHP_FALIAS(velocis_rollback,       birdstep_rollback,       arginfo_birdstep_rollback)
        PHP_FALIAS(velocis_fieldnum,       birdstep_fieldnum,       arginfo_birdstep_fieldnum)
        PHP_FALIAS(velocis_fieldname,      birdstep_fieldname,      arginfo_birdstep_fieldname)
/* End temporary aliases */
        {NULL, NULL, NULL}
};

zend_module_entry birdstep_module_entry = {
        STANDARD_MODULE_HEADER,
        "birdstep",
        birdstep_functions,
        PHP_MINIT(birdstep),
        PHP_MSHUTDOWN(birdstep),
        PHP_RINIT(birdstep),
        NULL,
        PHP_MINFO(birdstep),
        NO_VERSION_YET,
        STANDARD_MODULE_PROPERTIES
};

#ifdef COMPILE_DL_ODBC
ZEND_GET_MODULE(birdstep)
#endif

THREAD_LS birdstep_module php_birdstep_module;
THREAD_LS static HENV henv;

#define PHP_GET_BIRDSTEP_RES_IDX(id) if (!(res = birdstep_find_result(list, id))) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Not result index (%ld)", id); RETURN_FALSE; } 
#define PHP_BIRDSTEP_CHK_LNK(id) if (!(conn = birdstep_find_conn(list, id))) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Not connection index (%ld)", id); RETURN_FALSE; }
                                                        

static void _close_birdstep_link(zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
        VConn *conn = (VConn *)rsrc->ptr;

        if ( conn ) {
                efree(conn);
        }
}

static void _free_birdstep_result(zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
        Vresult *res = (Vresult *)rsrc->ptr;

        if ( res && res->values ) {
                register int i;
                for ( i=0; i < res->numcols; i++ ) {
                        if ( res->values[i].value )
                                efree(res->values[i].value);
                }
                efree(res->values);
        }
        if ( res ) {
                efree(res);
        }
}

PHP_MINIT_FUNCTION(birdstep)
{
        SQLAllocEnv(&henv);

        if ( cfg_get_long("birdstep.max_links",&php_birdstep_module.max_links) == FAILURE ) {
                php_birdstep_module.max_links = -1;
        }
        php_birdstep_module.num_links = 0;
        php_birdstep_module.le_link   = zend_register_list_destructors_ex(_close_birdstep_link, NULL, "birdstep link", module_number);
        php_birdstep_module.le_result = zend_register_list_destructors_ex(_free_birdstep_result, NULL, "birdstep result", module_number);

        return SUCCESS;
}

PHP_RINIT_FUNCTION(birdstep)
{
        return SUCCESS;
}


PHP_MINFO_FUNCTION(birdstep)
{
        php_info_print_table_start();
        php_info_print_table_row(2, "RAIMA Birdstep Support", "enabled" );
        php_info_print_table_end();
}

PHP_MSHUTDOWN_FUNCTION(birdstep)
{
        SQLFreeEnv(henv);
        return SUCCESS;
}

/* Some internal functions. Connections and result manupulate */

static int birdstep_add_conn(HashTable *list,VConn *conn,HDBC hdbc TSRMLS_DC)
{
        int ind;

        ind = zend_list_insert(conn,php_birdstep_module.le_link TSRMLS_CC);
        conn->hdbc = hdbc;
        conn->index = ind;

        return(ind);
}

static VConn * birdstep_find_conn(HashTable *list,int ind)
{
        VConn *conn;
        int type;

        conn = zend_list_find(ind,&type);
        if ( !conn || type != php_birdstep_module.le_link ) {
                return(NULL);
        }
        return(conn);
}

static void birdstep_del_conn(HashTable *list,int ind)
{
        zend_list_delete(ind);
}

static int birdstep_add_result(HashTable *list,Vresult *res,VConn *conn)
{
        int ind;

        ind = zend_list_insert(res,php_birdstep_module.le_result);
        res->conn = conn;
        res->index = ind;

        return(ind);
}

static Vresult * birdstep_find_result(HashTable *list,int ind)
{
        Vresult *res;
        int type;

        res = zend_list_find(ind,&type);
        if ( !res || type != php_birdstep_module.le_result ) {
                return(NULL);
        }
        return(res);
}

static void birdstep_del_result(HashTable *list,int ind)
{
        zend_list_delete(ind);
}

/* Users functions */

/* {{{ proto int birdstep_connect(string server, string user, string pass)
 */
PHP_FUNCTION(birdstep_connect)
{
        char *serv, *user, *pass;
        int serv_len, user_len, pass_len;
        RETCODE stat;
        HDBC hdbc;
        VConn *new;
        long ind;

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss", &serv, &serv_len, &user, &user_len, &pass, &pass_len) == FAILURE) {
                return;
        }
        
        if ( php_birdstep_module.max_links != -1 && php_birdstep_module.num_links == php_birdstep_module.max_links ) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Too many open connections (%d)",php_birdstep_module.num_links);
                RETURN_FALSE;
        }

        stat = SQLAllocConnect(henv,&hdbc);
        if ( stat != SQL_SUCCESS ) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Could not allocate connection handle");
                RETURN_FALSE;
        }
        stat = SQLConnect(hdbc, serv, SQL_NTS, user, SQL_NTS, pass, SQL_NTS);
        if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Could not connect to server \"%s\" for %s", serv, user);
                SQLFreeConnect(hdbc);
                RETURN_FALSE;
        }
        new = (VConn *)emalloc(sizeof(VConn));
        ind = birdstep_add_conn(list,new,hdbc TSRMLS_CC);
        php_birdstep_module.num_links++;
        RETURN_LONG(ind);
}
/* }}} */

/* {{{ proto bool birdstep_close(int id)
 */
PHP_FUNCTION(birdstep_close)
{
        long id;
        VConn *conn;

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &id) == FAILURE) {
                return;
        }

        PHP_BIRDSTEP_CHK_LNK(id);

        SQLDisconnect(conn->hdbc);
        SQLFreeConnect(conn->hdbc);
        birdstep_del_conn(list, id);
        php_birdstep_module.num_links--;
        RETURN_TRUE;
}
/* }}} */

/* {{{ proto int birdstep_exec(int index, string exec_str)
 */
PHP_FUNCTION(birdstep_exec)
{
        char *query;
        long ind;
        int query_len, indx;
        VConn *conn;
        Vresult *res;
        RETCODE stat;
        SWORD cols,i,colnamelen;
        SDWORD rows,coldesc;

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &ind, &query, &query_len) == FAILURE) {
                return;
        }

        PHP_BIRDSTEP_CHK_LNK(ind);

        res = (Vresult *)emalloc(sizeof(Vresult));
        stat = SQLAllocStmt(conn->hdbc,&res->hstmt);
        if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: SQLAllocStmt return %d",stat);
                efree(res);
                RETURN_FALSE;
        }
        stat = SQLExecDirect(res->hstmt,query,SQL_NTS);
        if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Cannot execute \"%s\" query",query);
                SQLFreeStmt(res->hstmt,SQL_DROP);
                efree(res);
                RETURN_FALSE;
        }
        /* Success query */
        stat = SQLNumResultCols(res->hstmt,&cols);
        if ( stat != SQL_SUCCESS ) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: SQLNumResultCols return %d",stat);
                SQLFreeStmt(res->hstmt,SQL_DROP);
                efree(res);
                RETURN_FALSE;
        }
        if ( !cols ) { /* Was INSERT, UPDATE, DELETE, etc. query */
                stat = SQLRowCount(res->hstmt,&rows);
                if ( stat != SQL_SUCCESS ) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: SQLNumResultCols return %d",stat);
                        SQLFreeStmt(res->hstmt,SQL_DROP);
                        efree(res);
                        RETURN_FALSE;
                }
                SQLFreeStmt(res->hstmt,SQL_DROP);
                efree(res);
                RETURN_LONG(rows);
        } else {  /* Was SELECT query */
                res->values = (VResVal *)safe_emalloc(sizeof(VResVal), cols, 0);
                res->numcols = cols;
                for ( i = 0; i < cols; i++ ) {
                        SQLColAttributes(res->hstmt,i+1,SQL_COLUMN_NAME,
                           res->values[i].name,sizeof(res->values[i].name),
                           &colnamelen,NULL);
                        SQLColAttributes(res->hstmt,i+1,SQL_COLUMN_TYPE,
                           NULL,0,NULL,&res->values[i].valtype);
                        switch ( res->values[i].valtype ) {
                                case SQL_LONGVARBINARY:
                                case SQL_LONGVARCHAR:
                                        res->values[i].value = NULL;
                                        continue;
                                default:
                                        break;
                        }
                        SQLColAttributes(res->hstmt,i+1,SQL_COLUMN_DISPLAY_SIZE,
                           NULL,0,NULL,&coldesc);
                        res->values[i].value = (char *)emalloc(coldesc+1);
                        SQLBindCol(res->hstmt,i+1,SQL_C_CHAR, res->values[i].value,coldesc+1, &res->values[i].vallen);
                }
        }
        res->fetched = 0;
        indx = birdstep_add_result(list,res,conn);
        RETURN_LONG(indx);
}
/* }}} */

/* {{{ proto bool birdstep_fetch(int index)
 */
PHP_FUNCTION(birdstep_fetch)
{
        long ind;
        Vresult *res;
        RETCODE stat;
        UDWORD  row;
        UWORD   RowStat[1];

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &ind) == FAILURE) {
                return;
        }

        PHP_GET_BIRDSTEP_RES_IDX(ind);

        stat = SQLExtendedFetch(res->hstmt,SQL_FETCH_NEXT,1,&row,RowStat);
        if ( stat == SQL_NO_DATA_FOUND ) {
                SQLFreeStmt(res->hstmt,SQL_DROP);
                birdstep_del_result(list,Z_LVAL_PP(ind));
                RETURN_FALSE;
        }
        if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: SQLFetch return error");
                SQLFreeStmt(res->hstmt,SQL_DROP);
                birdstep_del_result(list,Z_LVAL_PP(ind));
                RETURN_FALSE;
        }
        res->fetched = 1;
        RETURN_TRUE;
}
/* }}} */

/* {{{ proto mixed birdstep_result(int index, mixed col)
 */
PHP_FUNCTION(birdstep_result)
{
        zval **col;
        long ind;
        Vresult *res;
        RETCODE stat;
        int i,sql_c_type;
        UDWORD row;
        UWORD RowStat[1];
        SWORD indx = -1;
        char *field = NULL;

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lZ", &ind, &col) == FAILURE) {
                return;
        }

        PHP_GET_BIRDSTEP_RES_IDX(ind);

        if ( Z_TYPE_PP(col) == IS_STRING ) {
                field = Z_STRVAL_PP(col);
        } else {
                convert_to_long_ex(col);
                indx = Z_LVAL_PP(col);
        }
        if ( field ) {
                for ( i = 0; i < res->numcols; i++ ) {
                        if ( !strcasecmp(res->values[i].name,field)) {
                                indx = i;
                                break;
                        }
                }
                if ( indx < 0 ) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING,  "Field %s not found",field);
                        RETURN_FALSE;
                }
        } else {
                if ( indx < 0 || indx >= res->numcols ) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Field index not in range");
                        RETURN_FALSE;
                }
        }
        if ( !res->fetched ) {
                stat = SQLExtendedFetch(res->hstmt,SQL_FETCH_NEXT,1,&row,RowStat);
                if ( stat == SQL_NO_DATA_FOUND ) {
                        SQLFreeStmt(res->hstmt,SQL_DROP);
                        birdstep_del_result(list,Z_LVAL_PP(ind));
                        RETURN_FALSE;
                }
                if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: SQLFetch return error");
                        SQLFreeStmt(res->hstmt,SQL_DROP);
                        birdstep_del_result(list,Z_LVAL_PP(ind));
                        RETURN_FALSE;
                }
                res->fetched = 1;
        }
        switch ( res->values[indx].valtype ) {
                case SQL_LONGVARBINARY:
                        sql_c_type = SQL_C_BINARY;
                        goto l1;
                case SQL_LONGVARCHAR:
                        sql_c_type = SQL_C_CHAR;
l1:
                        if ( !res->values[indx].value ) {
                                res->values[indx].value = emalloc(4096);
                        }
                        stat = SQLGetData(res->hstmt,indx+1,sql_c_type,
                                res->values[indx].value,4095,&res->values[indx].vallen);
                        if ( stat == SQL_NO_DATA_FOUND ) {
                                SQLFreeStmt(res->hstmt,SQL_DROP);
                                birdstep_del_result(list,Z_LVAL_PP(ind));
                                RETURN_FALSE;
                        }
                        if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: SQLGetData return error");
                                SQLFreeStmt(res->hstmt,SQL_DROP);
                                birdstep_del_result(list,Z_LVAL_PP(ind));
                                RETURN_FALSE;
                        }
                        if ( res->values[indx].valtype == SQL_LONGVARCHAR ) {
                                RETURN_STRING(res->values[indx].value,TRUE);
                        } else {
                                RETURN_LONG((long)res->values[indx].value);
                        }
                default:
                        if ( res->values[indx].value != NULL ) {
                                RETURN_STRING(res->values[indx].value,TRUE);
                        }
        }
}
/* }}} */

/* {{{ proto bool birdstep_freeresult(int index)
 */
PHP_FUNCTION(birdstep_freeresult)
{
        long ind;
        Vresult *res;

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &ind) == FAILURE) {
                return;
        }

        PHP_GET_BIRDSTEP_RES_IDX(ind);

        SQLFreeStmt(res->hstmt,SQL_DROP);
        birdstep_del_result(list, ind);
        RETURN_TRUE;
}
/* }}} */

/* {{{ proto bool birdstep_autocommit(int index)
 */
PHP_FUNCTION(birdstep_autocommit)
{
        long id;
        RETCODE stat;
        VConn *conn;

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &id) == FAILURE) {
                return;
        }

        PHP_BIRDSTEP_CHK_LNK(id);

        stat = SQLSetConnectOption(conn->hdbc,SQL_AUTOCOMMIT,SQL_AUTOCOMMIT_ON);
        if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Set autocommit_on option failure");
                RETURN_FALSE;
        }
        RETURN_TRUE;
}
/* }}} */

/* {{{ proto bool birdstep_off_autocommit(int index)
 */
PHP_FUNCTION(birdstep_off_autocommit)
{
        long id;
        RETCODE stat;
        VConn *conn;

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &id) == FAILURE) {
                return;
        }

        PHP_BIRDSTEP_CHK_LNK(id);

        stat = SQLSetConnectOption(conn->hdbc,SQL_AUTOCOMMIT,SQL_AUTOCOMMIT_OFF);
        if ( stat != SQL_SUCCESS && stat != SQL_SUCCESS_WITH_INFO ) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Set autocommit_off option failure");
                RETURN_FALSE;
        }
        RETURN_TRUE;
}
/* }}} */

/* {{{ proto bool birdstep_commit(int index)
 */
PHP_FUNCTION(birdstep_commit)
{
        long id;
        RETCODE stat;
        VConn *conn;

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &id) == FAILURE) {
                return;
        }

        PHP_BIRDSTEP_CHK_LNK(id)

        stat = SQLTransact(NULL,conn->hdbc,SQL_COMMIT);
        if ( stat != SQL_SUCCESS ) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Commit failure");
                RETURN_FALSE;
        }
        RETURN_TRUE;
}
/* }}} */

/* {{{ proto bool birdstep_rollback(int index)
 */
PHP_FUNCTION(birdstep_rollback)
{
        long id;
        RETCODE stat;
        VConn *conn;

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &id) == FAILURE) {
                return;
        }

        PHP_BIRDSTEP_CHK_LNK(id);

        stat = SQLTransact(NULL,conn->hdbc,SQL_ROLLBACK);
        if ( stat != SQL_SUCCESS ) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Rollback failure");
                RETURN_FALSE;
        }
        RETURN_TRUE;
}
/* }}} */

/* {{{ proto string birdstep_fieldname(int index, int col)
 */
PHP_FUNCTION(birdstep_fieldname)
{
        long ind, col;
        Vresult *res;
        SWORD indx;

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &ind, &col) == FAILURE) {
                return;
        }

        PHP_GET_BIRDSTEP_RES_IDX(ind);

        indx = col;
        if ( indx < 0 || indx >= res->numcols ) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Birdstep: Field index not in range");
                RETURN_FALSE;
        }
        RETURN_STRING(res->values[indx].name,TRUE);
}
/* }}} */

/* {{{ proto int birdstep_fieldnum(int index)
 */
PHP_FUNCTION(birdstep_fieldnum)
{
        long ind;
        Vresult *res;

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &ind) == FAILURE) {
                return;
        }

        PHP_GET_BIRDSTEP_RES_IDX(ind);

        RETURN_LONG(res->numcols);
}
/* }}} */

#endif /* HAVE_BIRDSTEP */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 */

/* [<][>][^][v][top][bottom][index][help] */