Exemple #1
0
/*
** Commits the current transaction
*/
static int conn_commit(lua_State *L) {
    conn_data *conn = getconnection(L,1);

    isc_commit_retaining(conn->env->status_vector, &conn->transaction);
    if ( CHECK_DB_ERROR(conn->env->status_vector) )
        return return_db_error(L, conn->env->status_vector);

    lua_pushboolean(L, 1);
    return 1;
}
Exemple #2
0
EXPORT RM_ENTRY(rmc_commit_retaining)
{
	ClearParamPool();
	ISC_STATUS *stat = AllocStatusPool();
	isc_commit_retaining(stat,
						 (isc_tr_handle *)arg_vector[1].a_address);
	StatusToCobol(&arg_vector[0], stat);

	return (0);
}
Exemple #3
0
/*
** Executes a SQL statement.
** Returns
**   cursor object: if there are results or
**   row count: number of rows affected by statement if no results
*/
static int conn_execute (lua_State *L) {
    conn_data *conn = getconnection(L,1);
    const char *statement = luaL_checkstring(L, 2);
    int dialect = (int)luaL_optnumber(L, 3, 3);

    XSQLVAR *var;
    long dtype;
    int i, n, count, stmt_type;

    cur_data cur;

    cur.closed = 0;
    cur.env = conn->env;
    cur.conn = conn;
    cur.stmt = NULL;

    cur.out_sqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(CURSOR_PREALLOC));
    cur.out_sqlda->version = SQLDA_VERSION1;
    cur.out_sqlda->sqln = CURSOR_PREALLOC;

    /* create a statement to handle the query */
    isc_dsql_allocate_statement(conn->env->status_vector, &conn->db, &cur.stmt);
    if ( CHECK_DB_ERROR(conn->env->status_vector) ) {
        free(cur.out_sqlda);
        return return_db_error(L, conn->env->status_vector);
    }

    /* process the SQL ready to run the query */
    isc_dsql_prepare(conn->env->status_vector, &conn->transaction, &cur.stmt, 0, (char*)statement, dialect, cur.out_sqlda);
    if ( CHECK_DB_ERROR(conn->env->status_vector) ) {
        free(cur.out_sqlda);
        return return_db_error(L, conn->env->status_vector);
    }

    /* what type of SQL statement is it? */
    stmt_type = get_statement_type(&cur);
    if(stmt_type < 0) {
        free(cur.out_sqlda);
        return return_db_error(L, conn->env->status_vector);
    }

    /* an unsupported SQL statement (something like COMMIT) */
    if(stmt_type > 5) {
        free(cur.out_sqlda);
        return luasql_faildirect(L, "unsupported SQL statement");
    }

    /* resize the result set if needed */
    if (cur.out_sqlda->sqld > cur.out_sqlda->sqln)
    {
        n = cur.out_sqlda->sqld;
        free(cur.out_sqlda);
        cur.out_sqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(n));
        cur.out_sqlda->sqln = n;
        cur.out_sqlda->version = SQLDA_VERSION1;
        isc_dsql_describe(conn->env->status_vector, &cur.stmt, 1, cur.out_sqlda);
        if ( CHECK_DB_ERROR(conn->env->status_vector) ) {
            free(cur.out_sqlda);
            return return_db_error(L, conn->env->status_vector);
        }
    }

    /* prep the result set ready to handle the data */
    for (i=0, var = cur.out_sqlda->sqlvar; i < cur.out_sqlda->sqld; i++, var++) {
        dtype = (var->sqltype & ~1); /* drop flag bit for now */
        switch(dtype) {
        case SQL_VARYING:
            var->sqldata = (char *)malloc(sizeof(char)*var->sqllen + 2);
            break;
        case SQL_TEXT:
            var->sqldata = (char *)malloc(sizeof(char)*var->sqllen);
            break;
        case SQL_SHORT:
            var->sqldata = (char *)malloc(sizeof(short));
            break;
        case SQL_LONG:
            var->sqldata = (char *)malloc(sizeof(long));
            break;
        case SQL_INT64:
            var->sqldata = (char *)malloc(sizeof(ISC_INT64));
            break;
        case SQL_FLOAT:
            var->sqldata = (char *)malloc(sizeof(float));
            break;
        case SQL_DOUBLE:
            var->sqldata = (char *)malloc(sizeof(double));
            break;
        case SQL_TYPE_TIME:
            var->sqldata = (char *)malloc(sizeof(ISC_TIME));
            break;
        case SQL_TYPE_DATE:
            var->sqldata = (char *)malloc(sizeof(ISC_DATE));
            break;
        case SQL_TIMESTAMP:
            var->sqldata = (char *)malloc(sizeof(ISC_TIMESTAMP));
            break;
        case SQL_BLOB:
            var->sqldata = (char *)malloc(sizeof(ISC_QUAD));
            break;
            /* TODO : add extra data type handles here */
        }

        if (var->sqltype & 1) {
            /* allocate variable to hold NULL status */
            var->sqlind = (short *)malloc(sizeof(short));
        } else {
            var->sqlind = NULL;
        }
    }

    /* run the query */
    isc_dsql_execute(conn->env->status_vector, &conn->transaction, &cur.stmt, 1, NULL);
    if ( CHECK_DB_ERROR(conn->env->status_vector) ) {
        free_cur(&cur);
        return return_db_error(L, conn->env->status_vector);
    }

    /* if autocommit is set and it's a non SELECT query, commit change */
    if(conn->autocommit != 0 && stmt_type > 1) {
        isc_commit_retaining(conn->env->status_vector, &conn->transaction);
        if ( CHECK_DB_ERROR(conn->env->status_vector) ) {
            free_cur(&cur);
            return return_db_error(L, conn->env->status_vector);
        }
    }

    /* what do we return? a cursor or a count */
    if(cur.out_sqlda->sqld > 0) { /* a cursor */
        cur_data* user_cur;
        /* open the cursor ready for fetch cycles */
        isc_dsql_set_cursor_name(cur.env->status_vector, &cur.stmt, "dyn_cursor", (unsigned short)NULL);
        if ( CHECK_DB_ERROR(conn->env->status_vector) ) {
            free_cur(&cur);
            return return_db_error(L, conn->env->status_vector);
        }

        /* copy the cursor into a new lua userdata object */
        user_cur = (cur_data*)lua_newuserdata(L, sizeof(cur_data));
        luasql_setmeta (L, LUASQL_CURSOR_FIREBIRD);

        memcpy((void*)user_cur, (void*)&cur, sizeof(cur_data));

        /* add cursor to the lock count */
        lua_registerobj(L, 1, conn);
        ++conn->lock;
    } else { /* a count */
        if( (count = count_rows_affected(&cur)) < 0 ) {
            free(cur.out_sqlda);
            return return_db_error(L, conn->env->status_vector);
        }

        lua_pushnumber(L, count);

        /* totaly finnished with the cursor */
        isc_dsql_free_statement(conn->env->status_vector, &cur.stmt, DSQL_drop);
        free(cur.out_sqlda);
    }

    return 1;
}
Exemple #4
0
ISC_STATUS API_ROUTINE gds__commit_retaining(ISC_STATUS* status_vector, FB_API_HANDLE* tra_handle)
{
	return isc_commit_retaining(status_vector, tra_handle);
}