/********************************************************** * MODULE: mysql * AUTHOR(S): Radim Blazek (radim.blazek@gmail.com) * PURPOSE: MySQL database driver * COPYRIGHT: (C) 2001 by the GRASS Development Team * This program is free software under the * GNU General Public License (>=v2). * Read the file COPYING that comes with GRASS * for details. **********************************************************/ #include #include #include #include #include #include "globals.h" #include "proto.h" 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 = mysql_fetch_row(c->res); break; case DB_CURRENT: break; case DB_PREVIOUS: case DB_FIRST: case DB_LAST: default: append_error ( _("Cursor position is not supported " "by MySQL driver") ); report_error(); return DB_FAILED; } G_debug ( 3, "row = %d nrows = %d", c->row, c->nrows ); if ( c->row == NULL ) { *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, sqltype, mysqltype; dbColumn *column; dbValue *value; char *val; col = c->cols[i]; /* known column */ column = db_get_table_column (table, i); mysqltype = db_get_column_host_type(column); sqltype = db_get_column_sqltype(column); value = db_get_column_value (column); db_zero_string (&value->s); value->t.year = 0; value->t.month = 0; value->t.day = 0; value->t.hour = 0; value->t.minute = 0; value->t.seconds = 0.0; val = c->row[i]; if ( !val ) { value->isNull = 1; continue; } else { value->isNull = 0; } G_debug (3, "col %d, mysqltype %d, sqltype %d, val = '%s'", col, mysqltype, sqltype, c->row[col] ); /* defined in /usr/include/mysql/mysql_com.h */ switch (mysqltype) { int ns; case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_LONG: case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONGLONG: case MYSQL_TYPE_YEAR: value->i = atoi ( val ); break; case MYSQL_TYPE_FLOAT: case MYSQL_TYPE_DOUBLE: value->d = atof ( val ); break; /* MySQL TIMESTAMP < 4.1: YYYYMMDDHHMMSS TIMESTAMP(14) * YYMMDDHHMMSS TIMESTAMP(12) * YYMMDDHHMM TIMESTAMP(10) * YYYYMMDD TIMESTAMP(8) * YYMMDD TIMESTAMP(6) * YYMM TIMESTAMP(4) * YY YY * MySQL TIMESTAMP >= 4.1: 'YYYY-MM-DD HH:MM:SS' (19 chars) */ case MYSQL_TYPE_TIMESTAMP: { char valbuf[25], buf[10]; memset ( valbuf, 0, 25 ); strcpy ( valbuf, val ); switch ( strlen(val) ) { case 2: case 4: case 6: case 10: case 12: strncpy ( buf, val, 2 ); buf[2] = 0; value->t.year = atoi ( buf ); strncpy ( buf, val+2, 2 ); buf[2] = 0; value->t.month = atoi ( buf ); strncpy ( buf, val+4, 2 ); buf[2] = 0; value->t.day = atoi ( buf ); strncpy ( buf, val+6, 2 ); buf[2] = 0; value->t.hour = atoi ( buf ); strncpy ( buf, val+8, 2 ); buf[2] = 0; value->t.minute = atoi ( buf ); strncpy ( buf, val+10, 2 ); buf[2] = 0; value->t.seconds = atof ( buf ); break; case 8: case 14: strncpy ( buf, val, 4 ); buf[4] = 0; value->t.year = atoi ( buf ); strncpy ( buf, val+4, 2 ); buf[2] = 0; value->t.month = atoi ( buf ); strncpy ( buf, val+6, 2 ); buf[2] = 0; value->t.day = atoi ( buf ); strncpy ( buf, val+8, 2 ); buf[2] = 0; value->t.hour = atoi ( buf ); strncpy ( buf, val+10, 2 ); buf[2] = 0; value->t.minute = atoi ( buf ); strncpy ( buf, val+12, 2 ); buf[2] = 0; value->t.seconds = atof ( buf ); break; case 19: ns = sscanf( val, "%4d-%2d-%2d %2d:%2d:%lf", &(value->t.year), &(value->t.month), &(value->t.day), &(value->t.hour), &(value->t.minute), &(value->t.seconds) ); if ( ns != 6 ) { append_error ( _("Cannot scan timestamp: ") ); append_error ( val ); report_error(); return DB_FAILED; } break; default: append_error ( _("Unknown timestamp format: ") ); append_error ( val ); report_error(); return DB_FAILED; } } break; /* MySQL DATE: 'YYYY-MM-DD' */ case MYSQL_TYPE_DATE: ns = sscanf( val, "%4d-%2d-%2d", &(value->t.year), &(value->t.month), &(value->t.day) ); if ( ns != 3 ) { append_error ( _("Cannot scan date: ") ); append_error ( val ); report_error(); return DB_FAILED; } break; /* MySQL DATETIME: 'HH:MM:SS' */ case MYSQL_TYPE_TIME: ns = sscanf( val, "%2d:%2d:%lf", &(value->t.hour), &(value->t.minute), &(value->t.seconds) ); if ( ns != 3 ) { append_error ( _("Cannot scan time: ") ); append_error ( val ); report_error(); return DB_FAILED; } break; /* MySQL DATETIME: 'YYYY-MM-DD HH:MM:SS' */ case MYSQL_TYPE_DATETIME: ns = sscanf( val, "%4d-%2d-%2d %2d:%2d:%lf", &(value->t.year), &(value->t.month), &(value->t.day), &(value->t.hour), &(value->t.minute), &(value->t.seconds) ); if ( ns != 6 ) { append_error ( _("Cannot scan datetime: ") ); append_error ( val ); report_error(); return DB_FAILED; } break; case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_SET: case MYSQL_TYPE_ENUM: case MYSQL_TYPE_BLOB: db_set_string ( &(value->s), val ); break; } } G_debug (3, "Row fetched" ); return DB_OK; } int db__driver_get_num_rows (cn ) 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 ); }