"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "plugin/odbc_import.c" between
gretl-2020a.tar.xz and gretl-2020b.tar.xz

About: gretl (Gnu Regression, Econometrics and Time-series Library) is a cross-platform statistical package mainly for econometric analysis.

odbc_import.c  (gretl-2020a.tar.xz):odbc_import.c  (gretl-2020b.tar.xz)
skipping to change at line 145 skipping to change at line 145
return "??"; return "??";
} }
} }
/* Try connecting to data source. If @penv is NULL we're just checking /* Try connecting to data source. If @penv is NULL we're just checking
that it can be opened OK, otherwise we return a connection. that it can be opened OK, otherwise we return a connection.
*/ */
static SQLHDBC static SQLHDBC
gretl_odbc_connect_to_dsn (ODBC_info *odinfo, SQLHENV *penv, gretl_odbc_connect_to_dsn (ODBC_info *odinfo, SQLHENV *penv,
int *err) PRN *prn, int *err)
{ {
SQLHENV OD_env = NULL; /* ODBC environment handle */ SQLHENV OD_env = NULL; /* ODBC environment handle */
SQLHDBC dbc = NULL; /* connection handle */ SQLHDBC dbc = NULL; /* connection handle */
SQLRETURN ret; /* return value from functions */ SQLRETURN ret; /* return value from functions */
unsigned char status[10]; /* SQL status */ unsigned char status[10]; /* SQL status */
SQLINTEGER OD_err; SQLINTEGER OD_err;
SQLSMALLINT mlen; SQLSMALLINT mlen;
char *uname, *pword; char *uname, *pword;
unsigned char msg[512]; unsigned char msg[512];
skipping to change at line 194 skipping to change at line 194
ret = SQLConnect(dbc, (SQLCHAR *) odinfo->dsn, SQL_NTS, ret = SQLConnect(dbc, (SQLCHAR *) odinfo->dsn, SQL_NTS,
(SQLCHAR *) uname, (uname == NULL)? 0 : SQL_NTS, (SQLCHAR *) uname, (uname == NULL)? 0 : SQL_NTS,
(SQLCHAR *) pword, (pword == NULL)? 0 : SQL_NTS); (SQLCHAR *) pword, (pword == NULL)? 0 : SQL_NTS);
if (OD_error(ret)) { if (OD_error(ret)) {
gretl_errmsg_set("Error in SQLConnect"); gretl_errmsg_set("Error in SQLConnect");
SQLGetDiagRec(SQL_HANDLE_DBC, dbc, 1, status, SQLGetDiagRec(SQL_HANDLE_DBC, dbc, 1, status,
&OD_err, msg, 512, &mlen); &OD_err, msg, 512, &mlen);
gretl_errmsg_set((char *) msg); gretl_errmsg_set((char *) msg);
fprintf(stderr, " odinfo->dsn = '%s'\n", odinfo->dsn); pprintf(prn, " odinfo->dsn = '%s'\n", odinfo->dsn);
fprintf(stderr, " odinfo->username = '%s'\n", odinfo->username); pprintf(prn, " odinfo->username = '%s'\n", odinfo->username);
*err = 1; *err = 1;
} else if (prn != NULL) {
pprintf(prn, "SQLConnect(dbc,...): %s\n", sql_status(ret));
} }
bailout: bailout:
if (*err || penv == NULL) { if (*err || penv == NULL) {
/* either we bombed out, or we're just checking and the handles /* either we bombed out, or we're just checking and the handles
are not really wanted */ are not really wanted */
if (dbc != NULL) { if (dbc != NULL) {
ret = SQLDisconnect(dbc); ret = SQLDisconnect(dbc);
fprintf(stderr, "SQLDisconnect(dbc): %s\n", sql_status(ret)); pprintf(prn, "SQLDisconnect(dbc): %s\n", sql_status(ret));
ret = SQLFreeHandle(SQL_HANDLE_DBC, dbc); ret = SQLFreeHandle(SQL_HANDLE_DBC, dbc);
fprintf(stderr, "SQLFreeHandle(SQL_HANDLE_DBC, dbc): %s\n", sql_statu s(ret)); pprintf(prn, "SQLFreeHandle(SQL_HANDLE_DBC, dbc): %s\n", sql_status(r et));
dbc = NULL; dbc = NULL;
} }
if (OD_env != NULL) { if (OD_env != NULL) {
ret = SQLFreeHandle(SQL_HANDLE_ENV, OD_env); ret = SQLFreeHandle(SQL_HANDLE_ENV, OD_env);
fprintf(stderr, "SQLFreeHandle(SQL_HANDLE_ENV, OD_env): %s\n", sql_st atus(ret)); pprintf(prn, "SQLFreeHandle(SQL_HANDLE_ENV, OD_env): %s\n", sql_statu s(ret));
} }
} else { } else {
*penv = OD_env; *penv = OD_env;
} }
return dbc; return dbc;
} }
int gretl_odbc_check_dsn (ODBC_info *odinfo) int gretl_odbc_check_dsn (ODBC_info *odinfo)
{ {
int err = 0; int err = 0;
gretl_odbc_connect_to_dsn(odinfo, NULL, &err); gretl_odbc_connect_to_dsn(odinfo, NULL, NULL, &err);
return err; return err;
} }
static double strval_to_double (ODBC_info *odinfo, const char *s, static double strval_to_double (ODBC_info *odinfo, const char *s,
int r, int c, int *err) int r, int c, int *err)
{ {
if (odinfo->gst != NULL) { if (odinfo->gst != NULL) {
return gretl_string_table_index(odinfo->gst, s, c, 0, NULL); return gretl_string_table_index(odinfo->gst, s, c, 0, NULL);
} else if (numeric_string(s)) { } else if (numeric_string(s)) {
return atof(s); return atof(s);
} else { } else {
gretl_errmsg_sprintf(_("Expected numeric data, found string:\n" gretl_errmsg_sprintf(_("Expected numeric data, found string:\n"
"'%s' at row %d, column %d\n"), "'%s' at row %d, column %d\n"),
s, r, c); s, r, c);
*err = E_DATA; *err = E_DATA;
return NADBL; return NADBL;
} }
} }
#define ODBC_DEBUG 0 static double date_to_double (ODBC_info *odinfo, DATE_STRUCT *dv,
int r, int c, int *err)
{
gint16 y = dv->year;
gint16 m = dv->month;
gint16 d = dv->day;
return 10000*y + 100*m + d;
}
static void obsbit_from_sql_date (char *targ, DATE_STRUCT *dv)
{
guint16 y = dv->year;
guint16 m = dv->month;
guint16 d = dv->day;
if (y > 9999 || m > 12 || d > 31) {
*targ = '\0';
} else {
sprintf(targ, "%04d-%02d-%02d", (int) y, (int) m, (int) d);
}
}
static int odbc_read_rows (ODBC_info *odinfo, SQLHSTMT stmt, static int odbc_read_rows (ODBC_info *odinfo,
int totcols, SQLLEN *colbytes, SQLHSTMT stmt,
long *grabint, double *grabx, int totcols,
char **grabstr, double *xt, SQLLEN *colbytes,
int *nrows, int *obsgot, long *grabint,
char **strvals) double *grabx,
char **grabstr,
DATE_STRUCT *grabd,
double *xt,
DATE_STRUCT **dv,
int *nrows,
int *obsgot,
char **strvals,
PRN *prn)
{ {
char obsbit[OBSLEN]; char obsbit[OBSLEN];
SQLRETURN ret; SQLRETURN ret;
int i, j, k, p, v; int verbose = (prn != NULL);
int i, j, k, p, q, v;
int t = 0, err = 0; int t = 0, err = 0;
ret = SQLFetch(stmt); ret = SQLFetch(stmt);
while (ret == SQL_SUCCESS && !err) { while (ret == SQL_SUCCESS && !err) {
j = k = p = v = 0; j = k = p = q = v = 0;
#if ODBC_DEBUG if (verbose) {
fprintf(stderr, "Fetch, row %d: ", t); pprintf(prn, "Fetch, row %d: ", t);
#endif }
for (i=0; i<totcols && !err; i++) { for (i=0; i<totcols && !err; i++) {
#if ODBC_DEBUG if (verbose) {
fprintf(stderr, "col %d: ", i); pprintf(prn, "col %d: ", i);
#endif }
if (i < odinfo->obscols) { if (i < odinfo->obscols) {
/* looking for obs identifier chunk(s) */ /* looking for obs identifier chunk(s) */
*obsbit = '\0'; *obsbit = '\0';
if (colbytes[i] == SQL_NULL_DATA) { if (colbytes[i] == SQL_NULL_DATA) {
#if ODBC_DEBUG if (verbose) {
fputs("null data", stderr); pputs(prn, "null data");
#endif }
continue; /* error? */ continue; /* error? */
} }
#if ODBC_DEBUG if (verbose) {
fprintf(stderr, "%d bytes", (int) colbytes[i]); pprintf(prn, "%d bytes", (int) colbytes[i]);
#endif }
if (odinfo->coltypes[i] == GRETL_TYPE_INT) { if (odinfo->coltypes[i] == GRETL_TYPE_INT) {
sprintf(obsbit, odinfo->fmts[i], (int) grabint[j++]); sprintf(obsbit, odinfo->fmts[i], (int) grabint[j++]);
} else if (odinfo->coltypes[i] == GRETL_TYPE_STRING || } else if (odinfo->coltypes[i] == GRETL_TYPE_STRING) {
odinfo->coltypes[i] == GRETL_TYPE_DATE) {
sprintf(obsbit, odinfo->fmts[i], grabstr[k++]); sprintf(obsbit, odinfo->fmts[i], grabstr[k++]);
} else if (odinfo->coltypes[i] == GRETL_TYPE_DATE) {
obsbit_from_sql_date(obsbit, &grabd[q++]);
} else if (odinfo->coltypes[i] == GRETL_TYPE_DOUBLE) { } else if (odinfo->coltypes[i] == GRETL_TYPE_DOUBLE) {
sprintf(obsbit, odinfo->fmts[i], grabx[p++]); sprintf(obsbit, odinfo->fmts[i], grabx[p++]);
} }
if (odinfo->S != NULL && *obsbit != '\0') { if (odinfo->S != NULL && *obsbit != '\0') {
if (strlen(odinfo->S[t]) + strlen(obsbit) > OBSLEN - 1) { if (strlen(odinfo->S[t]) + strlen(obsbit) > OBSLEN - 1) {
fprintf(stderr, "Overflow in observation string!\n"); fprintf(stderr, "Overflow in observation string!\n");
} else { } else {
strcat(odinfo->S[t], obsbit); strcat(odinfo->S[t], obsbit);
} }
} }
#if ODBC_DEBUG if (verbose && i == odinfo->obscols - 1 && odinfo->S != NULL) {
if (i == odinfo->obscols - 1 && odinfo->S != NULL) {
/* finished composing obs string, report it */ /* finished composing obs string, report it */
fprintf(stderr, " (obs = '%s')", odinfo->S[t]); pprintf(prn, " (obs '%s')", odinfo->S[t]);
} }
#endif
} else { } else {
/* now looking for actual data */ /* now looking for actual data */
if (colbytes[i] == SQL_NULL_DATA) { if (colbytes[i] == SQL_NULL_DATA) {
fprintf(stderr, "no data"); if (verbose) {
pputs(prn, "no data");
}
odinfo->X[v][t] = NADBL; odinfo->X[v][t] = NADBL;
} else if (strvals != NULL && strvals[v] != NULL) { } else if (strvals != NULL && strvals[v] != NULL) {
odinfo->X[v][t] = strval_to_double(odinfo, strvals[v], odinfo->X[v][t] = strval_to_double(odinfo, strvals[v],
t+1, v+1, &err); t+1, v+1, &err);
#if ODBC_DEBUG if (verbose) {
fprintf(stderr, "string data value '%s' -> %g", strvals[v], o pprintf(prn, "string '%s' -> %g", strvals[v],
dinfo->X[v][t]); odinfo->X[v][t]);
#endif }
} else if (dv != NULL && dv[v] != NULL) {
odinfo->X[v][t] = date_to_double(odinfo, dv[v],
t+1, v+1, &err);
if (verbose) {
pprintf(prn, "date -> %g", odinfo->X[v][t]);
}
} else { } else {
odinfo->X[v][t] = xt[v]; odinfo->X[v][t] = xt[v];
#if ODBC_DEBUG if (verbose) {
fprintf(stderr, "data value %g", xt[v]); pprintf(prn, "value %g", xt[v]);
#endif }
} }
v++; v++;
} }
#if ODBC_DEBUG if (verbose && i < totcols-1) pputs(prn, "; ");
if (i < totcols-1) fputs("; ", stderr);
#endif
} /* end loop across columns */ } /* end loop across columns */
#if ODBC_DEBUG
fputc('\n', stderr);
#endif
if (verbose) {
pputc(prn, '\n');
}
t++; t++;
/* try getting next row */ /* try getting next row */
ret = SQLFetch(stmt); ret = SQLFetch(stmt);
if (ret == SQL_SUCCESS && t >= *nrows) { if (ret == SQL_SUCCESS && t >= *nrows) {
err = expand_catchment(odinfo, nrows); err = expand_catchment(odinfo, nrows);
} }
} } /* end loop across rows */
if (ret != SQL_SUCCESS && ret != SQL_NO_DATA && !err) { if (ret != SQL_SUCCESS && ret != SQL_NO_DATA && !err) {
err = E_DATA; err = E_DATA;
} }
*obsgot = t; *obsgot = t;
return err; return err;
} }
skipping to change at line 384 skipping to change at line 422
return G; return G;
} }
/* Allocate a char *object of size @len to hold a /* Allocate a char *object of size @len to hold a
string value provided by ODBC. If the array to hold string value provided by ODBC. If the array to hold
such objects has not yet been allocated if must be such objects has not yet been allocated if must be
be created first. be created first.
*/ */
static char *get_bind_target (char ***pS, int len, int nv, static char *get_str_bind_target (char ***pS, int len, int nv,
int j, int *err) int j, int *err)
{ {
char *ret = NULL; char *ret = NULL;
if (*pS == NULL) { if (*pS == NULL) {
/* starting from scratch */ /* starting from scratch */
*pS = strings_array_new(nv); *pS = strings_array_new(nv);
if (*pS == NULL) { if (*pS == NULL) {
*err = E_ALLOC; *err = E_ALLOC;
} }
} }
skipping to change at line 409 skipping to change at line 447
if ((*pS)[j] == NULL) { if ((*pS)[j] == NULL) {
*err = E_ALLOC; *err = E_ALLOC;
} else { } else {
ret = (*pS)[j]; ret = (*pS)[j];
} }
} }
return ret; return ret;
} }
static const char *sql_datatype_name (SQLSMALLINT dt) static DATE_STRUCT *get_date_bind_target (DATE_STRUCT ***pds,
int nv, int j,
int *err)
{
DATE_STRUCT *ret = NULL;
if (*pds == NULL) {
/* starting from scratch */
*pds = calloc(sizeof *pds, nv);
if (*pds == NULL) {
*err = E_ALLOC;
}
}
if (*pds != NULL) {
(*pds)[j] = calloc(sizeof **pds, 1);
if ((*pds)[j] == NULL) {
*err = E_ALLOC;
} else {
ret = (*pds)[j];
}
}
return ret;
}
static gchar *sql_datatype_name (SQLSMALLINT dt, int *free_it)
{ {
switch (dt) { switch (dt) {
case SQL_UNKNOWN_TYPE: return "SQL_UNKNOWN_TYPE";
case SQL_CHAR: return "SQL_CHAR"; case SQL_CHAR: return "SQL_CHAR";
case SQL_DATE: return "SQL_DATE";
case SQL_NUMERIC: return "SQL_NUMERIC"; case SQL_NUMERIC: return "SQL_NUMERIC";
case SQL_DECIMAL: return "SQL_DECIMAL"; case SQL_DECIMAL: return "SQL_DECIMAL";
case SQL_INTEGER: return "SQL_INTEGER"; case SQL_INTEGER: return "SQL_INTEGER";
case SQL_SMALLINT: return "SQL_SMALLINT"; case SQL_SMALLINT: return "SQL_SMALLINT";
case SQL_FLOAT: return "SQL_FLOAT"; case SQL_FLOAT: return "SQL_FLOAT";
case SQL_REAL: return "SQL_REAL"; case SQL_REAL: return "SQL_REAL";
case SQL_DOUBLE: return "SQL_DOUBLE"; case SQL_DOUBLE: return "SQL_DOUBLE";
case SQL_DATETIME: return "SQL_DATETIME";
case SQL_VARCHAR: return "SQL_VARCHAR"; case SQL_VARCHAR: return "SQL_VARCHAR";
case SQL_WCHAR: return "SQL_WCHAR"; case SQL_WCHAR: return "SQL_WCHAR";
case SQL_WVARCHAR: return "SQL_WVARCHAR"; case SQL_WVARCHAR: return "SQL_WVARCHAR";
case SQL_TYPE_DATE: return "SQL_DATE"; /* odbc bug ?? */
} }
fprintf(stderr, "sql_datatype_name: got dt = %d\n", dt); /* note: as of 2020-03-22 we're not supporting SQL_TIMESTAMP */
return "invalid";
if (free_it != NULL) {
*free_it = 1;
return g_strdup_printf("%d (?)", (int) dt);
} else {
fprintf(stderr, "data type %d not recognized or not supported\n", dt);
return NULL;
}
}
static gchar *sql_nullable_name (SQLSMALLINT nv, int *free_it)
{
if (nv == SQL_NO_NULLS) {
return "SQL_NO_NULLS";
} else if (nv == SQL_NULLABLE) {
return "SQL_NULLABLE";
} else {
*free_it = 1;
return g_strdup_printf("nullable %d (?)", (int) nv);
}
} }
#define IS_SQL_DATE(t) (t == SQL_DATE || t == SQL_TYPE_DATE)
#define IS_SQL_STRING_TYPE(t) (t == SQL_CHAR || \ #define IS_SQL_STRING_TYPE(t) (t == SQL_CHAR || \
t == SQL_VARCHAR || \ t == SQL_VARCHAR || \
t == SQL_WCHAR || \ t == SQL_WCHAR || \
t == SQL_WVARCHAR) t == SQL_WVARCHAR)
static SQLSMALLINT get_col_info (SQLHSTMT stmt, int colnum, static SQLSMALLINT get_col_info (SQLHSTMT stmt, int colnum,
int *len, int *err) int *len, PRN *prn, int *err)
{ {
SQLCHAR colname[128+1] = {0}; SQLCHAR colname[128+1] = {0};
SQLSMALLINT colname_len; SQLSMALLINT colname_len;
SQLSMALLINT data_type; SQLSMALLINT data_type;
SQLULEN colsize; SQLULEN colsize;
SQLSMALLINT digits; SQLSMALLINT digits;
SQLSMALLINT nullable; SQLSMALLINT nullable;
SQLRETURN ret; SQLRETURN ret;
ret = SQLDescribeCol(stmt, /* handle of stmt */ ret = SQLDescribeCol(stmt, /* handle of stmt */
colnum, /* column number */ colnum, /* column number */
colname, /* where to put column name */ colname, /* where to put column name */
sizeof(colname), /* = 128+1 ... allow for nul */ sizeof(colname), /* = 128+1 ... allow for nul */
&colname_len, /* where to put name length */ &colname_len, /* location for name length */
&data_type, /* where to put <data type> */ &data_type, /* location for <data type> */
&colsize, /* where to put column size */ &colsize, /* location for column size */
&digits, /* where to put scale/frac precision * &digits, /* location for scale/frac precision *
/ /
&nullable); /* where to put null/not-null flag */ &nullable); /* location for 'nullable' flag */
if (OD_error(ret)) { if (OD_error(ret)) {
gretl_errmsg_set("Error in SQLDescribeCol"); gretl_errmsg_set("Error in SQLDescribeCol");
*err = E_DATA; *err = E_DATA;
} else if (sql_datatype_name(data_type, NULL) == NULL) {
gretl_errmsg_sprintf("col %d: unsupported data type %d", colnum,
(int) data_type);
*err = E_DATA;
} else if (len != NULL) { } else if (len != NULL) {
fprintf(stderr, " col %d (%s): data_type %s, size %d, digits %d, nullable if (prn != NULL) {
%d\n", int free1 = 0, free2 = 0;
colnum, colname, sql_datatype_name(data_type), (int) colsize, gchar *dname = sql_datatype_name(data_type, &free1);
digits, nullable); gchar *nname = sql_nullable_name(nullable, &free2);
pprintf(prn, " col %d (%s): data_type %s, size %d, digits %d, %s\n",
colnum, colname, dname, (int) colsize, digits, nname);
if (free1) g_free(dname);
if (free2) g_free(nname);
}
*len = (int) colsize; *len = (int) colsize;
} }
return data_type; return data_type;
} }
int gretl_odbc_get_data (ODBC_info *odinfo) int gretl_odbc_get_data (ODBC_info *odinfo, gretlopt opt, PRN *inprn)
{ {
SQLHENV OD_env = NULL; /* ODBC environment handle */ SQLHENV OD_env = NULL; /* ODBC environment handle */
SQLHDBC dbc = NULL; /* connection handle */ SQLHDBC dbc = NULL; /* connection handle */
SQLHSTMT stmt = NULL; /* statement handle */ SQLHSTMT stmt = NULL; /* statement handle */
SQLRETURN ret; /* return value from SQL functions */ SQLRETURN ret; /* return value from SQL functions */
unsigned char status[10]; /* SQL status */ unsigned char status[10]; /* SQL status */
unsigned char msg[512]; unsigned char msg[512];
SQLINTEGER OD_err; SQLINTEGER OD_err;
SQLSMALLINT mlen, ncols, dt; SQLSMALLINT mlen, ncols, dt;
double *xt = NULL; double *xt = NULL;
SQLLEN *colbytes = NULL; SQLLEN *colbytes = NULL;
SQLLEN sqlnrows; SQLLEN sqlnrows;
long grabint[ODBC_OBSCOLS]; long grabint[ODBC_OBSCOLS];
double grabx[ODBC_OBSCOLS]; double grabx[ODBC_OBSCOLS];
DATE_STRUCT grabd[ODBC_OBSCOLS];
DATE_STRUCT **dv = NULL;
char **grabstr = NULL; char **grabstr = NULL;
char **strvals = NULL; char **strvals = NULL;
int *svlist = NULL; int *svlist = NULL;
int totcols, nrows = 0, nstrs = 0; int totcols, nrows = 0;
int i, j, k, p; int nstrs = 0;
int i, j, k, p, q;
int T = 0, err = 0; int T = 0, err = 0;
PRN *prn;
odinfo->X = NULL; odinfo->X = NULL;
odinfo->S = NULL; odinfo->S = NULL;
odinfo->nrows = 0; odinfo->nrows = 0;
status[0] = msg[0] = 0;
prn = (opt & OPT_V)? inprn : NULL;
/* columns used in composing obs identifier (if any) plus /* columns used in composing obs identifier (if any) plus
actual data columns */ actual data columns */
totcols = odinfo->obscols + odinfo->nvars; totcols = odinfo->obscols + odinfo->nvars;
xt = malloc(odinfo->nvars * sizeof *xt); xt = malloc(odinfo->nvars * sizeof *xt);
if (xt == NULL) { if (xt == NULL) {
return E_ALLOC; return E_ALLOC;
} }
skipping to change at line 518 skipping to change at line 621
return E_ALLOC; return E_ALLOC;
} }
grabstr = allocate_string_grabbers(odinfo, &nstrs, &err); grabstr = allocate_string_grabbers(odinfo, &nstrs, &err);
if (err) { if (err) {
free(xt); free(xt);
free(colbytes); free(colbytes);
return err; return err;
} }
dbc = gretl_odbc_connect_to_dsn(odinfo, &OD_env, &err); dbc = gretl_odbc_connect_to_dsn(odinfo, &OD_env, prn, &err);
if (err) { if (err) {
free(xt); free(xt);
free(colbytes); free(colbytes);
strings_array_free(grabstr, nstrs); strings_array_free(grabstr, nstrs);
return err; return err;
} }
ret = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt); ret = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
if (OD_error(ret)) { if (OD_error(ret)) {
gretl_errmsg_set("Error in AllocStatement"); gretl_errmsg_set("Error in AllocStatement");
SQLGetDiagRec(SQL_HANDLE_DBC, dbc, 1, status, &OD_err, SQLGetDiagRec(SQL_HANDLE_DBC, dbc, 1, status, &OD_err,
msg, 512, &mlen); msg, 512, &mlen);
gretl_errmsg_set((char *) msg); gretl_errmsg_set((char *) msg);
err = 1; err = 1;
goto bailout; goto bailout;
} }
j = k = p = 0; j = k = p = q = 0;
/* bind auxiliary (obs) columns */ /* bind auxiliary (obs) columns */
for (i=0; i<odinfo->obscols; i++) { for (i=0; i<odinfo->obscols; i++) {
colbytes[i] = 0; colbytes[i] = 0;
if (odinfo->coltypes[i] == GRETL_TYPE_INT) { if (odinfo->coltypes[i] == GRETL_TYPE_INT) {
SQLBindCol(stmt, i+1, SQL_C_LONG, &grabint[j++], 0, SQLBindCol(stmt, i+1, SQL_C_LONG, &grabint[j++], 0,
&colbytes[i]); &colbytes[i]);
} else if (odinfo->coltypes[i] == GRETL_TYPE_STRING) { } else if (odinfo->coltypes[i] == GRETL_TYPE_STRING) {
SQLBindCol(stmt, i+1, SQL_C_CHAR, grabstr[k++], ODBC_STRSZ, SQLBindCol(stmt, i+1, SQL_C_CHAR, grabstr[k++], ODBC_STRSZ,
&colbytes[i]); &colbytes[i]);
} else if (odinfo->coltypes[i] == GRETL_TYPE_DATE) { } else if (odinfo->coltypes[i] == GRETL_TYPE_DATE) {
SQLBindCol(stmt, i+1, SQL_C_TYPE_DATE, grabstr[k++], 10, SQLBindCol(stmt, i+1, SQL_C_TYPE_DATE, &grabd[q++], 10,
&colbytes[i]); &colbytes[i]);
} else if (odinfo->coltypes[i] == GRETL_TYPE_DOUBLE) { } else if (odinfo->coltypes[i] == GRETL_TYPE_DOUBLE) {
SQLBindCol(stmt, i+1, SQL_C_DOUBLE, &grabx[p++], sizeof(double), SQLBindCol(stmt, i+1, SQL_C_DOUBLE, &grabx[p++], sizeof(double),
&colbytes[i]); &colbytes[i]);
} }
} }
ret = SQLExecDirect(stmt, (SQLCHAR *) odinfo->query, SQL_NTS); ret = SQLExecDirect(stmt, (SQLCHAR *) odinfo->query, SQL_NTS);
if (OD_error(ret)) { if (OD_error(ret)) {
gretl_errmsg_set("Error in SQLExecDirect"); gretl_errmsg_set("Error in SQLExecDirect");
fprintf(stderr, "failed query: '%s'\n", odinfo->query); pprintf(prn, "failed query: '%s'\n", odinfo->query);
SQLGetDiagRec(SQL_HANDLE_DBC, dbc, 1, status, &OD_err, msg, SQLGetDiagRec(SQL_HANDLE_STMT, stmt, 1, status, &OD_err, msg,
100, &mlen); 100, &mlen);
gretl_errmsg_set((char *) msg); if (msg[0] != 0) {
gretl_errmsg_set((char *) msg);
}
err = 1; err = 1;
goto bailout; goto bailout;
} }
ret = SQLNumResultCols(stmt, &ncols); ret = SQLNumResultCols(stmt, &ncols);
if (OD_error(ret)) { if (OD_error(ret)) {
gretl_errmsg_set("Error in SQLNumResultCols"); gretl_errmsg_set("Error in SQLNumResultCols");
err = 1; err = 1;
goto bailout; goto bailout;
} }
fprintf(stderr, "Number of columns = %d\n", (int) ncols); pprintf(prn, "Number of columns = %d\n", (int) ncols);
if (ncols != totcols) { if (ncols != totcols) {
gretl_errmsg_sprintf("ODBC: expected %d columns but got %d", gretl_errmsg_sprintf("ODBC: expected %d columns but got %d",
totcols, ncols); totcols, ncols);
err = 1; err = 1;
goto bailout; goto bailout;
} else if (ncols <= 0) { } else if (ncols <= 0) {
gretl_errmsg_set("Didn't get any data"); gretl_errmsg_set("Didn't get any data");
err = E_DATA; err = E_DATA;
goto bailout; goto bailout;
} }
/* are we going to need a string table? */ /* Are we going to need a string table? */
j = 1; j = 1;
for (i=odinfo->obscols; i<ncols && !err; i++) { for (i=odinfo->obscols; i<ncols && !err; i++) {
dt = get_col_info(stmt, i+1, NULL, &err); dt = get_col_info(stmt, i+1, NULL, prn, &err);
if (!err && IS_SQL_STRING_TYPE(dt)) { if (!err && IS_SQL_STRING_TYPE(dt)) {
svlist = gretl_list_append_term(&svlist, j++); pprintf(prn, "string table: adding ID %d\n", j);
svlist = gretl_list_append_term(&svlist, j);
} }
j++;
} }
if (svlist != NULL) { if (!err && svlist != NULL) {
odinfo->gst = gretl_string_table_new(svlist); odinfo->gst = gretl_string_table_new(svlist);
if (odinfo->gst == NULL) { if (odinfo->gst == NULL) {
err = E_ALLOC; err = E_ALLOC;
goto bailout; goto bailout;
} }
} }
/* show and process column info */ /* show and process column info */
for (i=0; i<ncols && !err; i++) { for (i=0; i<ncols && !err; i++) {
int len = 0; int len = 0;
dt = get_col_info(stmt, i+1, &len, &err); dt = get_col_info(stmt, i+1, &len, prn, &err);
if (!err && i >= odinfo->obscols) { if (!err && i >= odinfo->obscols) {
/* bind data columns */ /* bind data columns */
colbytes[i] = 0; colbytes[i] = 0;
j = i - odinfo->obscols; j = i - odinfo->obscols;
if (IS_SQL_STRING_TYPE(dt)) { if (IS_SQL_STRING_TYPE(dt)) {
char *sval = get_bind_target(&strvals, len, odinfo->nvars, j, &er r); char *sval = get_str_bind_target(&strvals, len, odinfo->nvars, j, &err);
if (!err) { if (!err) {
fprintf(stderr, " binding data col %d to strvals[%d] (len = % d)\n", pprintf(prn, " binding col %d to strvals[%d] (len = %d)\n",
i+1, j, len); i+1, j, len);
SQLBindCol(stmt, i+1, SQL_C_CHAR, sval, len, &colbytes[i]); SQLBindCol(stmt, i+1, SQL_C_CHAR, sval, len, &colbytes[i]);
} }
} else if (IS_SQL_DATE(dt)) {
DATE_STRUCT *ds = get_date_bind_target(&dv, odinfo->nvars, j, &er
r);
if (!err) {
pprintf(prn, " binding col %d to dv[%d]\n", i+1, j);
SQLBindCol(stmt, i+1, SQL_C_TYPE_DATE, ds, sizeof *ds,
&colbytes[i]);
}
} else { } else {
/* should be numerical data */ /* should be numerical data */
pprintf(prn, " binding col %d to xt[%d]\n", i+1, j);
SQLBindCol(stmt, i+1, SQL_C_DOUBLE, &xt[j], sizeof(double), SQLBindCol(stmt, i+1, SQL_C_DOUBLE, &xt[j], sizeof(double),
&colbytes[i]); &colbytes[i]);
} }
} }
} }
if (err) { if (err) {
goto bailout; goto bailout;
} }
skipping to change at line 645 skipping to change at line 761
goto bailout; goto bailout;
} }
/* Note that SQLRowCount can give nrows <= 0, even while returning /* Note that SQLRowCount can give nrows <= 0, even while returning
SQL_SUCCESS, if the ODBC driver is too lazy to compute the SQL_SUCCESS, if the ODBC driver is too lazy to compute the
number of rows in the result before actually fetching the data number of rows in the result before actually fetching the data
(e.g. Microsoft but maybe also others). (e.g. Microsoft but maybe also others).
*/ */
nrows = sqlnrows; nrows = sqlnrows;
fprintf(stderr, "Number of Rows (from SQLRowCount) = %d\n", nrows); pprintf(prn, "Number of rows (from SQLRowCount): %d\n", nrows);
if (!err) { if (!err) {
if (nrows <= 0) { if (nrows <= 0) {
nrows = ODBC_INIT_ROWS; nrows = ODBC_INIT_ROWS;
} }
odinfo->X = doubles_array_new(odinfo->nvars, nrows); odinfo->X = doubles_array_new(odinfo->nvars, nrows);
if (odinfo->X == NULL) { if (odinfo->X == NULL) {
err = E_ALLOC; err = E_ALLOC;
} }
} }
skipping to change at line 667 skipping to change at line 783
if (!err && odinfo->fmts != NULL) { if (!err && odinfo->fmts != NULL) {
odinfo->S = strings_array_new_with_length(nrows, OBSLEN); odinfo->S = strings_array_new_with_length(nrows, OBSLEN);
if (odinfo->S == NULL) { if (odinfo->S == NULL) {
err = E_ALLOC; err = E_ALLOC;
} }
} }
if (!err) { if (!err) {
/* get the actual data */ /* get the actual data */
err = odbc_read_rows(odinfo, stmt, totcols, colbytes, err = odbc_read_rows(odinfo, stmt, totcols, colbytes,
grabint, grabx, grabstr, xt, grabint, grabx, grabstr, grabd,
&nrows, &T, strvals); xt, dv, &nrows, &T, strvals, prn);
} }
bailout: bailout:
if (err) { if (err) {
doubles_array_free(odinfo->X, odinfo->nvars); doubles_array_free(odinfo->X, odinfo->nvars);
odinfo->X = NULL; odinfo->X = NULL;
strings_array_free(odinfo->S, nrows); strings_array_free(odinfo->S, nrows);
odinfo->S = NULL; odinfo->S = NULL;
} else { } else {
skipping to change at line 697 skipping to change at line 813
odinfo->nrows = T; odinfo->nrows = T;
} }
free(xt); free(xt);
free(colbytes); free(colbytes);
free(svlist); free(svlist);
strings_array_free(grabstr, nstrs); strings_array_free(grabstr, nstrs);
if (strvals != NULL) { if (strvals != NULL) {
strings_array_free(strvals, odinfo->nvars); strings_array_free(strvals, odinfo->nvars);
} }
if (dv != NULL) {
for (i=0; i<odinfo->nvars; i++) {
free(dv[i]);
}
free(dv);
}
if (stmt != NULL) { if (stmt != NULL) {
ret = SQLFreeHandle(SQL_HANDLE_STMT, stmt); ret = SQLFreeHandle(SQL_HANDLE_STMT, stmt);
fprintf(stderr, "SQLFreeHandle(SQL_HANDLE_STMT): %s\n", sql_status(ret)); pprintf(prn, "SQLFreeHandle(SQL_HANDLE_STMT): %s\n", sql_status(ret));
} }
ret = SQLDisconnect(dbc); ret = SQLDisconnect(dbc);
fprintf(stderr, "SQLDisconnect: %s\n", sql_status(ret)); pprintf(prn, "SQLDisconnect: %s\n", sql_status(ret));
ret = SQLFreeHandle(SQL_HANDLE_DBC, dbc); ret = SQLFreeHandle(SQL_HANDLE_DBC, dbc);
fprintf(stderr, "SQLFreeHandle(SQL_HANDLE_DBC): %s\n", sql_status(ret)); pprintf(prn, "SQLFreeHandle(SQL_HANDLE_DBC): %s\n", sql_status(ret));
ret = SQLFreeHandle(SQL_HANDLE_ENV, OD_env); ret = SQLFreeHandle(SQL_HANDLE_ENV, OD_env);
fprintf(stderr, "SQLFreeHandle(SQL_HANDLE_ENV): %s\n", sql_status(ret)); pprintf(prn, "SQLFreeHandle(SQL_HANDLE_ENV): %s\n", sql_status(ret));
return err; return err;
} }
 End of changes. 66 change blocks. 
91 lines changed or deleted 212 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)