SQLRETURN MNDBFetch(ODBCStmt *stmt, SQLUSMALLINT *RowStatusArray) { ODBCDesc *ard, *ird; ODBCDescRec *rec; int i; SQLULEN row; SQLLEN offset; /* stmt->startRow is the (0 based) index of the first row we * stmt->need to fetch */ ard = stmt->ApplRowDescr; ird = stmt->ImplRowDescr; stmt->retrieved = 0; stmt->currentCol = 0; stmt->rowSetSize = 0; stmt->currentRow = stmt->startRow + 1; if (mapi_seek_row(stmt->hdl, stmt->startRow, MAPI_SEEK_SET) != MOK) { /* Row value out of range */ addStmtError(stmt, "HY107", mapi_error_str(stmt->Dbc->mid), 0); return SQL_ERROR; } stmt->State = FETCHED; if (stmt->retrieveData == SQL_RD_OFF) { /* don't really retrieve the data, just do as if, updating the SQL_DESC_ARRAY_STATUS_PTR */ stmt->rowSetSize = ard->sql_desc_array_size; if (stmt->startRow + stmt->rowSetSize > (SQLLEN) stmt->rowcount) stmt->rowSetSize = stmt->rowcount - stmt->startRow; if (stmt->rowSetSize <= 0) { stmt->rowSetSize = 0; return SQL_NO_DATA; } if (RowStatusArray) { for (row = 0; (SQLLEN) row < stmt->rowSetSize; row++) { WriteValue(RowStatusArray, SQL_ROW_SUCCESS); RowStatusArray++; } for (; row < ard->sql_desc_array_size; row++) { WriteValue(RowStatusArray, SQL_ROW_NOROW); RowStatusArray++; } } return SQL_SUCCESS; } if (ard->sql_desc_bind_offset_ptr) offset = *ard->sql_desc_bind_offset_ptr; else offset = 0; for (row = 0; row < ard->sql_desc_array_size; row++) { if (mapi_fetch_row(stmt->hdl) == 0) { switch (mapi_error(stmt->Dbc->mid)) { case MOK: if (row == 0) return SQL_NO_DATA; break; case MTIMEOUT: if (RowStatusArray) WriteValue(RowStatusArray, SQL_ROW_ERROR); /* Timeout expired / Communication * link failure */ addStmtError(stmt, stmt->Dbc->sql_attr_connection_timeout ? "HYT00" : "08S01", mapi_error_str(stmt->Dbc->mid), 0); return SQL_ERROR; default: if (RowStatusArray) WriteValue(RowStatusArray, SQL_ROW_ERROR); /* General error */ addStmtError(stmt, "HY000", mapi_error_str(stmt->Dbc->mid), 0); return SQL_ERROR; } break; } if (RowStatusArray) WriteValue(RowStatusArray, SQL_ROW_SUCCESS); stmt->rowSetSize++; for (i = 1; i <= ird->sql_desc_count; i++) ird->descRec[i].already_returned = 0; for (i = 1; i <= ard->sql_desc_count; i++) { rec = &ard->descRec[i]; if (rec->sql_desc_data_ptr == NULL) continue; stmt->retrieved = 0; if (ODBCFetch(stmt, i, rec->sql_desc_concise_type, rec->sql_desc_data_ptr, rec->sql_desc_octet_length, rec->sql_desc_octet_length_ptr, rec->sql_desc_indicator_ptr, rec->sql_desc_precision, rec->sql_desc_scale, rec->sql_desc_datetime_interval_precision, offset, row) == SQL_ERROR) { if (RowStatusArray) WriteValue(RowStatusArray, SQL_ROW_SUCCESS_WITH_INFO); } } if (RowStatusArray) RowStatusArray++; } if (ird->sql_desc_rows_processed_ptr) *ird->sql_desc_rows_processed_ptr = (SQLULEN) stmt->rowSetSize; if (RowStatusArray) while (row++ < ard->sql_desc_array_size) { WriteValue(RowStatusArray, SQL_ROW_NOROW); RowStatusArray++; } return stmt->Error ? SQL_SUCCESS_WITH_INFO : SQL_SUCCESS; }
int main(int argc, char **argv) { Mapi dbh; MapiHdl hdl = NULL; mapi_int64 rows, i; char *parm[] = { "peter", 0 }; char *parm2[] = { "25", 0 }; int j; if (argc != 4) { printf("usage:%s <host> <port> <language>\n", argv[0]); exit(-1); } dbh = mapi_connect(argv[1], atoi(argv[2]), "monetdb", "monetdb", argv[3], NULL); if (dbh == NULL || mapi_error(dbh)) die(dbh, hdl); /* mapi_trace(dbh, 1); */ if (strcmp(argv[3], "sql") == 0) { /* switch of autocommit */ if (mapi_setAutocommit(dbh, 0) != MOK || mapi_error(dbh)) die(dbh,NULL); if ((hdl = mapi_query(dbh, "create table emp(name varchar(20), age int)")) == NULL || mapi_error(dbh)) die(dbh, hdl); if (mapi_close_handle(hdl) != MOK) die(dbh, hdl); if ((hdl = mapi_query(dbh, "insert into emp values('John', 23)")) == NULL || mapi_error(dbh)) die(dbh, hdl); if (mapi_close_handle(hdl) != MOK) die(dbh, hdl); if ((hdl = mapi_query(dbh, "insert into emp values('Mary', 22)")) == NULL || mapi_error(dbh)) die(dbh, hdl); if (mapi_close_handle(hdl) != MOK) die(dbh, hdl); if ((hdl = mapi_query(dbh, "select * from emp")) == NULL || mapi_error(dbh)) die(dbh, hdl); } else if (strcmp(argv[3], "mal") == 0) { if ((hdl = mapi_query(dbh, "emp := bat.new(:oid,:str);")) == NULL || mapi_error(dbh)) die(dbh, hdl); if ((hdl = mapi_query(dbh, "age := bat.new(:oid,:int);")) == NULL || mapi_error(dbh)) die(dbh, hdl); if (mapi_close_handle(hdl) != MOK) die(dbh, hdl); if ((hdl = mapi_query_array(dbh, "bat.append(emp,\"?\");", parm)) == NULL || mapi_error(dbh)) die(dbh, hdl); if ((hdl = mapi_query_array(dbh, "bat.append(age,?);", parm2)) == NULL || mapi_error(dbh)) die(dbh, hdl); if (mapi_close_handle(hdl) != MOK) die(dbh, hdl); if ((hdl = mapi_query(dbh, "io.print(emp,age);")) == NULL || mapi_error(dbh)) die(dbh, hdl); } else { fprintf(stderr, "%s: unknown language, only mal and sql supported\n", argv[0]); exit(1); } /* Retrieve all tuples in the client cache first */ rows = mapi_fetch_all_rows(hdl); if (mapi_error(dbh)) die(dbh, hdl); printf("rows received " LLFMT " with %d fields\n", rows, mapi_get_field_count(hdl)); /* Interpret the cache as a two-dimensional array */ for (i = 0; i < rows; i++) { if (mapi_seek_row(hdl, i, MAPI_SEEK_SET) || mapi_fetch_row(hdl) == 0) break; for (j = 0; j < mapi_get_field_count(hdl); j++) { printf("%s=%s ", mapi_get_name(hdl, j), mapi_fetch_field(hdl, j)); } printf("\n"); } if (mapi_error(dbh)) die(dbh, hdl); if (mapi_close_handle(hdl) != MOK) die(dbh, hdl); mapi_destroy(dbh); return 0; }
CAMLprim value mapi_seek_row_stub(value handle, value rownr, value whence) { mapi_int64 i = Int64_val(rownr); MapiMsg msg = mapi_seek_row((MapiHdl) handle, i, Int_val(whence)); return Val_int(index_of_msg(msg)); }
SQLRETURN SQL_API SQLSetPos(SQLHSTMT StatementHandle, SQLSETPOSIROW RowNumber, SQLUSMALLINT Operation, SQLUSMALLINT LockType) { ODBCStmt *stmt = (ODBCStmt *) StatementHandle; #ifdef ODBCDEBUG ODBCLOG("SQLSetPos " PTRFMT " " ULENFMT " %s %s\n", PTRFMTCAST StatementHandle, ULENCAST RowNumber, translateOperation(Operation), translateLockType(LockType)); #endif if (!isValidStmt(stmt)) return SQL_INVALID_HANDLE; clearStmtErrors(stmt); /* check the parameter values */ if (stmt->State < EXECUTED0) { /* Function sequence error */ addStmtError(stmt, "HY010", NULL, 0); return SQL_ERROR; } if (stmt->State <= EXECUTED1) { /* Invalid cursor state */ addStmtError(stmt, "24000", NULL, 0); return SQL_ERROR; } if (RowNumber > (SQLSETPOSIROW) stmt->rowSetSize) { /* Row value out of range */ addStmtError(stmt, "HY107", NULL, 0); return SQL_ERROR; } if (stmt->cursorType == SQL_CURSOR_FORWARD_ONLY) { /* Invalid cursor position */ addStmtError(stmt, "HY109", NULL, 0); return SQL_ERROR; } switch (LockType) { case SQL_LOCK_NO_CHANGE: /* the only value that we support */ break; case SQL_LOCK_EXCLUSIVE: case SQL_LOCK_UNLOCK: /* Optional feature not implemented */ addStmtError(stmt, "HYC00", NULL, 0); return SQL_ERROR; default: /* Invalid attribute/option identifier */ addStmtError(stmt, "HY092", NULL, 0); return SQL_ERROR; } switch (Operation) { case SQL_POSITION: if (RowNumber == 0) { /* Invalid cursor position */ addStmtError(stmt, "HY109", NULL, 0); return SQL_ERROR; } if (mapi_seek_row(stmt->hdl, stmt->startRow + RowNumber - 1, MAPI_SEEK_SET) != MOK) { /* Invalid cursor position */ addStmtError(stmt, "HY109", NULL, 0); return SQL_ERROR; } stmt->currentRow = stmt->startRow + RowNumber - 1; switch (mapi_fetch_row(stmt->hdl)) { case MOK: break; case MTIMEOUT: /* Connection timeout expired */ addStmtError(stmt, "HYT01", NULL, 0); return SQL_ERROR; default: /* Invalid cursor position */ addStmtError(stmt, "HY109", NULL, 0); return SQL_ERROR; } stmt->currentRow++; break; case SQL_REFRESH: case SQL_UPDATE: case SQL_DELETE: /* Optional feature not implemented */ addStmtError(stmt, "HYC00", NULL, 0); return SQL_ERROR; default: /* Invalid attribute/option identifier */ addStmtError(stmt, "HY092", NULL, 0); return SQL_ERROR; } return SQL_SUCCESS; }