EXPORT RM_ENTRY(rmc_dsql_set_cursor_name) { ClearParamPool(); ISC_STATUS *stat = AllocStatusPool(); isc_dsql_set_cursor_name(stat, (isc_stmt_handle *)arg_vector[1].a_address, (char *)CobolToString(&arg_vector[2]), *CobolToShort(&arg_vector[3])); StatusToCobol(&arg_vector[0], stat); return (0); }
void IB_Statement::setCursorName (const IB_STRING cursorName) { #ifdef IB_USER_API if (!cursorName || (strlen (cursorName) == 0)) throw new IB_SQLException ("Attempt to set cursor name to empty or null string"); #endif if (isc_dsql_set_cursor_name (status_->vector(), &stmtHandle_, cursorName, NULL)) throw new IB_SQLException (IB_SQLException::engine__default_0__, status_); cursorName_ = cursorName; }
/* ** 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; }