I am having some problems with the functions mapi_param*().
1. It seems mapi_param() really wants a char* cast to a char**. (See the
inner workings of mapi_param() vs. mapi_param_string().)
2. If mapi_param(), mapi_param_string() and mapi_param_type() get a
char*, the value used in the query does not change as the char* is
updated.
Using
mapi_bind_var( , , MAPI_INT, int*) and
mapi_bind_var( , , MAPI_VARCHAR, char**)
works as expected, while
mapi_param_type( , , MAPI_INT, MAPI_INT, int*) and
mapi_param_type( , , MAPI_VARCHAR, MAPI_VARCHAR, char**)
do not.
Is there something wrong with interface, or am I just using it wrong?
Here is how I have tried using the functions:
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include
using namespace std;
Mapi dbh;
void check(MapiHdl hdl, int ret = MOK, bool fatal = true) {
if (ret != MOK || hdl == NULL || mapi_error(dbh)) {
if (hdl) {
mapi_explain_result(hdl,stderr);
} else {
mapi_explain(dbh,stderr);
}
if (fatal) assert(0);//exit(-1);
}
}
void paramInt(MapiHdl hdl, int fldnr, int* val) {
int ret = mapi_param_type(hdl, fldnr, MAPI_INT, MAPI_INT, val);
check(hdl, ret);
}
void paramStr(MapiHdl hdl, int fldnr, char** val) {
// int ret = mapi_param(hdl, fldnr, val);
/* Case 1:
* QUERY = INSERT INTO t VALUES(1, p`)
* ERROR = !SELECT: identifier 'p`' unknown
* Cast to (void*) in call to mapi_param_type() in mapi_param().
*/
int ret = mapi_param(hdl, fldnr, (char**)*val);
/* Case 2:
* Works, sort of.
* Seems it wants a (char*) really.
* But 'foo' is inserted the second time instead of bar.
*/
// int ret = mapi_param_string(hdl, fldnr, MAPI_VARCHAR, *val, NULL);
/* 'foo' twice.
*/
// int ret = mapi_param_string(hdl, fldnr, MAPI_VARCHAR, (char*)val,
NULL);
/* As Case 1.
*/
// int ret = mapi_param_type(hdl, fldnr, MAPI_VARCHAR, MAPI_VARCHAR, val);
/* As Case 1.
*/
// int ret = mapi_param_type(hdl, fldnr, MAPI_VARCHAR, MAPI_VARCHAR,
*val);
/* 'foo' twice.
*/
check(hdl, ret);
}
int main() {
dbh = mapi_connect("localhost", 50000, "nilsgri", "nilsgri",
"sql", "proto");
MapiHdl hdl = mapi_query(dbh, "DROP TABLE t");
check(hdl, MOK, false);
mapi_close_handle(hdl);
hdl = mapi_query(dbh, "CREATE TABLE t (a INT, b VARCHAR(255))");
check(hdl);
mapi_close_handle(hdl);
hdl = mapi_prepare(dbh, "INSERT INTO t VALUES(?, ?)");
check(hdl);
int a = 1;
paramInt(hdl, 0, &a);
char* b1 = strdup("'foo'");
char* b = b1;
paramStr(hdl, 1, &b);
int ret = mapi_execute(hdl);
check(hdl, ret);
a = 2;
char* b2 = strdup("'bar'");
b = b2;
// paramStr(hdl, 1, &b); // I would like not having to do this.
ret = mapi_execute(hdl);
check(hdl, ret);
mapi_close_handle(hdl);
hdl = mapi_quick_query(dbh, "SELECT * FROM t", stderr);
check(hdl, ret);
mapi_close_handle(hdl);
mapi_disconnect(dbh);
mapi_destroy(dbh);
free(b1);
free(b2);
}