/* TODO: implement time zone handling */ #include #include #include #include "globals.h" #include "proto.h" #include int db__driver_fetch(dbCursor * cn, int position, int *more) { cursor *c; dbToken token; dbTable *table; int i; /* get cursor token */ token = db_get_cursor_token(cn); /* get the cursor by its token */ if (!(c = (cursor *) db_find_token(token))) { append_error("Cursor not found"); report_error(); return DB_FAILED; } /* fetch on position */ switch (position) { case DB_NEXT: c->row++; break; case DB_CURRENT: break; case DB_PREVIOUS: c->row--; break; case DB_FIRST: c->row = 0; break; case DB_LAST: c->row = c->nrows - 1; break; }; G_debug(3, "row = %d nrows = %d", c->row, c->nrows); if (c->row < 0 || c->row >= c->nrows) { *more = 0; return DB_OK; } *more = 1; /* get the data out of the descriptor into the table */ table = db_get_cursor_table(cn); for (i = 0; i < c->ncols; i++) { int col, gpgtype, sqltype; dbColumn *column; dbValue *value; col = c->cols[i]; /* known cols */ column = db_get_table_column(table, i); gpgtype = db_get_column_host_type(column); sqltype = db_get_column_sqltype(column); value = db_get_column_value(column); db_zero_string(&value->s); /* Is null? */ if (PQgetisnull(c->res, c->row, col)) { value->isNull = 1; continue; } else { value->isNull = 0; } G_debug(3, "row %d, col %d, gpgtype %d, sqltype %d: val = '%s'", c->row, col, gpgtype, sqltype, PQgetvalue(c->res, c->row, col)); switch (gpgtype) { int ns, tz; case PG_TYPE_CHAR: case PG_TYPE_BPCHAR: case PG_TYPE_VARCHAR: case PG_TYPE_TEXT: db_set_string(&(value->s), PQgetvalue(c->res, c->row, col)); break; case PG_TYPE_BIT: case PG_TYPE_INT2: case PG_TYPE_INT4: case PG_TYPE_INT8: case PG_TYPE_SERIAL: case PG_TYPE_OID: value->i = atoi(PQgetvalue(c->res, c->row, col)); break; case PG_TYPE_FLOAT4: case PG_TYPE_FLOAT8: case PG_TYPE_NUMERIC: value->d = atof(PQgetvalue(c->res, c->row, col)); break; /* Note: we have set DATESTYLE TO ISO in db_driver_open_select_cursor() so datetime * format should be ISO */ case PG_TYPE_DATE: /* Example: '1999-01-25' */ ns = sscanf(PQgetvalue(c->res, c->row, col), "%4d-%2d-%2d", &(value->t.year), &(value->t.month), &(value->t.day)); if (ns != 3) { append_error("Cannot scan date:"); append_error(PQgetvalue(c->res, c->row, col)); report_error(); return DB_FAILED; } value->t.hour = 0; value->t.minute = 0; value->t.seconds = 0.0; break; case PG_TYPE_TIME: /* Example: '04:05:06.25', '04:05:06' */ ns = sscanf(PQgetvalue(c->res, c->row, col), "%2d:%2d:%lf", &(value->t.hour), &(value->t.minute), &(value->t.seconds)); if (ns != 3) { append_error("Cannot scan time:"); append_error(PQgetvalue(c->res, c->row, col)); report_error(); return DB_FAILED; } value->t.year = 0; value->t.month = 0; value->t.day = 0; break; case PG_TYPE_TIMESTAMP: /* Example: '1999-01-25 04:05:06.25+01', '1999-01-25 04:05:06' */ ns = sscanf(PQgetvalue(c->res, c->row, col), "%4d-%2d-%2d %2d:%2d:%lf%3d", &(value->t.year), &(value->t.month), &(value->t.day), &(value->t.hour), &(value->t.minute), &(value->t.seconds), &tz); if (ns == 7) { append_error ("Cannot scan timestamp (no idea how to process time zone):"); append_error(PQgetvalue(c->res, c->row, col)); report_error(); return DB_FAILED; } else if (ns < 6) { append_error("Cannot scan timestamp (not enough arguments):"); append_error(PQgetvalue(c->res, c->row, col)); report_error(); return DB_FAILED; } break; case PG_TYPE_BOOL: if (strcmp(PQgetvalue(c->res, c->row, col), "t") == 0) db_set_string(&(value->s), "1"); else if (strcmp(PQgetvalue(c->res, c->row, col), "f") == 0) db_set_string(&(value->s), "0"); else G_warning(_("Cannot recognize boolean value")); break; } } G_debug(3, "Row fetched"); return DB_OK; } int db__driver_get_num_rows(dbCursor * cn) { cursor *c; dbToken token; /* get cursor token */ token = db_get_cursor_token(cn); /* get the cursor by its token */ if (!(c = (cursor *) db_find_token(token))) { append_error("Cursor not found"); report_error(); return DB_FAILED; } return (c->nrows); }