/********************************************************** * 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 "globals.h" #include "proto.h" int db__driver_describe_table( dbString *table_name, dbTable **table) { dbString sql; MYSQL_RES *res; db_init_string ( &sql ); db_set_string( &sql, "select * from "); db_append_string ( &sql, db_get_string(table_name) ); db_append_string( &sql, " where 1 = 0"); if ( mysql_query ( connection, db_get_string(&sql) ) != 0 ) { append_error ( db_get_string(&sql) ); append_error ( "\n" ); append_error ( mysql_error(connection) ); report_error(); return DB_FAILED; } res = mysql_store_result ( connection ); if ( res == NULL ) { append_error ( db_get_string(&sql) ); append_error ( "\n" ); append_error ( mysql_error(connection) ); report_error(); return DB_FAILED; } if ( describe_table( res, table, NULL) == DB_FAILED ) { append_error("Cannot describe table\n"); report_error(); mysql_free_result(res); return DB_FAILED; } mysql_free_result(res); db_set_table_name( *table, db_get_string(table_name) ); return DB_OK; } /* describe table, if c is not NULL cur->cols and cur->ncols is also set */ int describe_table( MYSQL_RES *res, dbTable **table, cursor *c) { int i, ncols, kcols; char *name; int sqltype, length; dbColumn *column; MYSQL_FIELD *fields; G_debug (3, "describe_table()"); ncols = mysql_num_fields ( res ); fields = mysql_fetch_fields ( res ); /* Count columns of known type */ kcols = 0; for (i = 0; i < ncols; i++) { field_info ( &(fields[i]), &sqltype, &length ); if ( sqltype == DB_SQL_TYPE_UNKNOWN ) continue; kcols++; /* known types */ } G_debug (3, "kcols = %d", kcols); if (!(*table = db_alloc_table(kcols))) { return DB_FAILED; } if ( c ) { c->ncols = kcols; c->cols = (int *) G_malloc ( kcols * sizeof(int) ); } db_set_table_name ( *table, "" ); db_set_table_description ( *table, "" ); /* Currently not used in GRASS */ /* db_set_table_delete_priv_granted (*table); db_set_table_insert_priv_granted (*table); db_set_table_delete_priv_not_granted (*table); db_set_table_insert_priv_not_granted (*table); */ kcols = 0; for ( i = 0; i < ncols; i++ ) { name = fields[i].name; field_info ( &(fields[i]), &sqltype, &length ); G_debug(3, "col: %s, kcols %d, sqltype %d", name, kcols, sqltype ); G_debug(3, "flags = %d", fields[i].flags ); if ( sqltype == DB_SQL_TYPE_UNKNOWN ) { /* Print warning and continue */ G_warning ( _("MySQL driver: column '%s', type %d " "is not supported"), name, fields[i].type); continue; } if ( fields[i].type == MYSQL_TYPE_LONGLONG ) G_warning ( _("column '%s' : type BIGINT is stored as " "integer (4 bytes) some data may be damaged"), name); column = db_get_table_column(*table, kcols); db_set_column_name(column, name); db_set_column_length(column, length); db_set_column_host_type(column, (int)fields[i].type); db_set_column_sqltype(column, sqltype); db_set_column_precision ( column, (int)fields[i].decimals ); db_set_column_scale ( column, 0 ); if ( !(fields[i].flags & NOT_NULL_FLAG ) ) { db_set_column_null_allowed(column); } db_set_column_has_undefined_default_value(column); db_unset_column_use_default_value(column); /* Currently not used in GRASS */ /* db_set_column_select_priv_granted (column); db_set_column_update_priv_granted (column); db_set_column_update_priv_not_granted (column); */ if ( c ) { c->cols[kcols] = i; } kcols++; } return DB_OK; } /* Get sqltype for field */ void field_info ( MYSQL_FIELD *field, int * sqltype, int * length ) { *length = field->length; switch ( field->type ) { case MYSQL_TYPE_TINY: *sqltype = DB_SQL_TYPE_SMALLINT; break; case MYSQL_TYPE_SHORT: case MYSQL_TYPE_LONG: case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONGLONG: *sqltype = DB_SQL_TYPE_INTEGER; break; case MYSQL_TYPE_DECIMAL: *sqltype = DB_SQL_TYPE_DECIMAL; break; case MYSQL_TYPE_FLOAT: *sqltype = DB_SQL_TYPE_REAL; break; case MYSQL_TYPE_DOUBLE: *sqltype = DB_SQL_TYPE_DOUBLE_PRECISION; break; case MYSQL_TYPE_TIMESTAMP: *sqltype = DB_SQL_TYPE_TIMESTAMP; break; case MYSQL_TYPE_DATE: *sqltype = DB_SQL_TYPE_DATE; break; case MYSQL_TYPE_TIME: *sqltype = DB_SQL_TYPE_TIME; break; case MYSQL_TYPE_DATETIME: //*sqltype = DB_SQL_TYPE_DATETIME; //*sqltype |= DB_DATETIME_MASK; *sqltype = DB_SQL_TYPE_TIMESTAMP; break; case MYSQL_TYPE_YEAR: *sqltype = DB_SQL_TYPE_INTEGER; break; case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_SET: case MYSQL_TYPE_ENUM: *sqltype = DB_SQL_TYPE_CHARACTER; break; case MYSQL_TYPE_BLOB: if ( field->flags & BINARY_FLAG ) { *sqltype = DB_SQL_TYPE_UNKNOWN; } else { *sqltype = DB_SQL_TYPE_TEXT; } break; case MYSQL_TYPE_GEOMETRY: case MYSQL_TYPE_NULL: *sqltype = DB_SQL_TYPE_UNKNOWN; break; default: *sqltype = DB_SQL_TYPE_UNKNOWN; } return; }