123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- /**
- * \file fetch.c
- *
- * \brief Low level SQLite database functions.
- *
- * This program is free software under the GNU General Public License
- * (>=v2). Read the file COPYING that comes with GRASS for details.
- *
- * \author Radim Blazek
- *
- * \date 2005-2007
- */
- #include <stdlib.h>
- #include <string.h>
- #include <grass/dbmi.h>
- #include <grass/glocale.h>
- #include "globals.h"
- #include "proto.h"
- /**
- * \fn int db__driver_fetch (dbCursor *cn, int position, int *more)
- *
- * \brief Low level SQLite database table record fetch.
- *
- * NOTE: <b>position</b> is one of:
- * DB_NEXT, DB_FIRST, DB_CURRENT, DB_PREVIOUS, DB_LAST.
- *
- * \param[in] cn open database cursor
- * \param[in] position database position. See NOTE.
- * \param[in,out] more 1 = more data; 0 = no more data
- * \return int
- */
- int
- db__driver_fetch (dbCursor *cn, int position, int *more)
- {
- cursor *c;
- dbToken token;
- dbTable *table;
- int i, ret;
- int ns;
- /* 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;
- }
- G_debug ( 3, "fetch row = %d", c->row );
- /* fetch on position */
- switch (position)
- {
- case DB_NEXT:
- case DB_FIRST:
- if ( position == DB_FIRST )
- c->row = -1;
- ret = sqlite3_step ( c->statement );
- if ( ret != SQLITE_ROW )
- {
- if ( ret != SQLITE_DONE )
- {
- append_error ("Cannot step:\n");
- append_error ((char *) sqlite3_errmsg (sqlite));
- report_error();
- return DB_FAILED;
- }
- sqlite3_reset ( c->statement );
- *more = 0;
- return DB_OK;
- }
- c->row++;
- break;
- case DB_CURRENT:
- break;
- case DB_PREVIOUS:
- append_error ("DB_PREVIOUS is not supported");
- report_error();
- return DB_FAILED;
- break;
- case DB_LAST:
- append_error ("DB_LAST is not supported");
- report_error();
- return DB_FAILED;
- break;
- };
- *more = 1;
- /* get the data out of the descriptor into the table */
- table = db_get_cursor_table(cn);
- for (i = 0; i < c->nkcols; i++)
- {
- int col, litetype, sqltype;
- dbColumn *column;
- dbValue *value;
- const char *text;
- dbDateTime *dt;
- col = c->kcols[i]; /* known cols */
-
- column = db_get_table_column (table, i);
- sqltype = db_get_column_sqltype(column);
- /* fails for dates:
- litetype = db_get_column_host_type(column);
- */
- litetype = sqlite3_column_type ( c->statement, col );
- text = (const char *) sqlite3_column_text ( c->statement, col);
- value = db_get_column_value (column);
- db_zero_string (&value->s);
-
- /* Is null? */
- if ( sqlite3_column_type(c->statement, col) == SQLITE_NULL ) {
- value->isNull = 1;
- continue;
- } else {
- value->isNull = 0;
- }
- G_debug (3, "col %d, litetype %d, sqltype %d: val = '%s'",
- col, litetype, sqltype, text );
- /* http://www.sqlite.org/capi3ref.html#sqlite3_column_type
- SQLITE_INTEGER 1
- SQLITE_FLOAT 2
- SQLITE_TEXT 3
- SQLITE_BLOB 4
- SQLITE_NULL 5
- lib/db/dbmi_base/sqltype.c defines:
- DB_SQL_TYPE_*
- */
- /* Note: we have set DATESTYLE TO ISO in db_driver_open_select_cursor() so datetime
- * format should be ISO */
- switch ( sqltype ) {
- case DB_SQL_TYPE_INTEGER:
- case DB_SQL_TYPE_SMALLINT:
- case DB_SQL_TYPE_SERIAL:
- value->i = sqlite3_column_int ( c->statement, col);
- break;
- case DB_SQL_TYPE_REAL:
- case DB_SQL_TYPE_DOUBLE_PRECISION:
- value->d = sqlite3_column_double ( c->statement, col);
- break;
- case DB_SQL_TYPE_DATE:
- dt = &value->t;
- dt->hour = 0;
- dt->minute = 0;
- dt->seconds = 0.0;
- G_debug(3, "sqlite fetched date: %s", text);
- ns = sscanf(text, "%4d-%2d-%2d",
- &dt->year, &dt->month, &dt->day);
- if ( ns != 3 ) {
- append_error ( "Cannot scan date:");
- append_error (text);
- report_error();
- return DB_FAILED;
- }
- break;
- case DB_SQL_TYPE_TIME:
- dt = &value->t;
- dt->year = 0;
- dt->month = 0;
- dt->day = 0;
- G_debug(3, "sqlite fetched date: %s", text);
- ns = sscanf(text, "%2d:%2d:%lf",
- &dt->hour, &dt->minute, &dt->seconds);
- if ( ns != 3 ) {
- append_error ( "Cannot scan time:");
- append_error (text);
- report_error();
- return DB_FAILED;
- }
- break;
- case DB_SQL_TYPE_TIMESTAMP:
- dt = &value->t;
- G_debug(3, "sqlite fetched timestamp: %s", text);
- ns = sscanf(text, "%4d-%2d-%2d %2d:%2d:%lf",
- &dt->year, &dt->month, &dt->day,
- &dt->hour, &dt->minute, &dt->seconds);
- if ( ns != 6 ) {
- append_error ( "Cannot scan timestamp:");
- append_error (text);
- report_error();
- return DB_FAILED;
- }
- break;
- case DB_SQL_TYPE_INTERVAL:
- dt = &value->t;
- dt->year = 0;
- dt->month = 0;
- dt->day = 0;
- dt->hour = 0;
- dt->minute = 0;
- G_debug(3, "sqlite fetched interval: %s", text);
- G_warning("SQLite driver: parsing of interval values not implemented; assuming seconds");
- ns = sscanf(text, "%lf", &dt->seconds);
- if ( ns != 1 ) {
- append_error ( "Cannot scan interval:");
- append_error (text);
- report_error();
- return DB_FAILED;
- }
- break;
- case DB_SQL_TYPE_DECIMAL:
- case DB_SQL_TYPE_NUMERIC:
- case DB_SQL_TYPE_CHARACTER:
- case DB_SQL_TYPE_TEXT:
- db_set_string ( &value->s, text);
- break;
- }
- }
- G_debug (3, "Row fetched" );
- return DB_OK;
- }
- /**
- * \fn int db__driver_get_num_rows (dbCursor *cn)
- *
- * \brief Gets number of rows in SQLite database table.
- *
- * \param[in] cn open database cursor
- * \return int number of rows in table
- */
- int
- db__driver_get_num_rows (dbCursor *cn)
- {
- cursor *c;
- dbToken token;
- int row;
- /* 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;
- }
- if ( c->nrows > -1 )
- {
- return ( c->nrows );
- }
- sqlite3_reset ( c->statement );
- c->nrows = 0;
- while ( sqlite3_step ( c->statement ) == SQLITE_ROW )
- {
- c->nrows++;
- }
- sqlite3_reset ( c->statement );
- /* Reset cursor position */
- row = -1;
- if ( c->row > -1 )
- {
- while ( sqlite3_step ( c->statement ) == SQLITE_ROW )
- {
- if ( row == c->row )
- break;
-
- row++;
- }
- }
- return ( c->nrows );
- }
|