📄 qgsgrassprovider.cpp
字号:
#endif dbCursor databaseCursor; if ( db_open_select_cursor(driver, &dbstr, &databaseCursor, DB_SCROLL) != DB_OK ){ db_close_database_shutdown_driver ( driver ); std::cerr << "Cannot select attributes from table" << std::endl; return att; } int nRecords = db_get_num_rows ( &databaseCursor );#ifdef QGISDEBUG std::cerr << "Number of records: " << nRecords << std::endl;#endif if ( nRecords < 1 ) { db_close_database_shutdown_driver ( driver ); std::cerr << "No DB record" << std::endl; return att; } dbTable *databaseTable = db_get_cursor_table (&databaseCursor); int nColumns = db_get_table_number_of_columns(databaseTable); int more; if ( db_fetch (&databaseCursor, DB_NEXT, &more) != DB_OK ) { db_close_database_shutdown_driver ( driver ); std::cout << "Cannot fetch DB record" << std::endl; return att; } // Read columns' description for (int i = 0; i < nColumns; i++) { dbColumn *column = db_get_table_column (databaseTable, i); db_convert_column_value_to_string (column, &dbstr); QString v = mEncoding->toUnicode(db_get_string(&dbstr)); std::cerr << "Value: " << v.toLocal8Bit().data() << std::endl; att->insert(i, QVariant( v ) ); } db_close_cursor (&databaseCursor); db_close_database_shutdown_driver ( driver ); db_free_string(&dbstr); return att;}QString *QgsGrassProvider::updateAttributes ( int field, int cat, const QString &values ){#ifdef QGISDEBUG std::cerr << "QgsGrassProvider::updateAttributes() field = " << field << " cat = " << cat << std::endl;#endif QString *error = new QString(); struct field_info *fi = Vect_get_field( mMap, field); // should work also with field = 0 // Read attributes if ( fi == NULL ) {#ifdef QGISDEBUG std::cerr << "No field info -> no attributes" << std::endl;#endif error->setLatin1( "Cannot get field info" ); return error; }#ifdef QGISDEBUG std::cerr << "Field info found -> open database" << std::endl;#endif QgsGrass::setMapset ( mGisdbase, mLocation, mMapset ); dbDriver *driver = db_start_driver_open_database ( fi->driver, fi->database ); if ( driver == NULL ) { std::cerr << "Cannot open database " << fi->database << " by driver " << fi->driver << std::endl; error->setAscii("Cannot open database"); return error; }#ifdef QGISDEBUG std::cerr << "Database opened -> read attributes" << std::endl;#endif dbString dbstr; db_init_string (&dbstr); QString query; query = "update " + QString(fi->table) + " set " + values + " where " + QString(fi->key) + " = " + QString::number(cat);#ifdef QGISDEBUG std::cerr << "query: " << query.toLocal8Bit().data() << std::endl;#endif // For some strange reason, mEncoding->fromUnicode(query) does not work, // but probably it is not correct, because Qt widgets will use current locales for input // -> it is possible to edit only in current locales at present // QCString qcs = mEncoding->fromUnicode(query); Q3CString qcs = query.toLocal8Bit().data();#ifdef QGISDEBUG std::cerr << "qcs: " << qcs.data() << std::endl;#endif char *cs = new char[qcs.length() + 1]; strcpy(cs, (const char *)qcs); db_set_string (&dbstr, cs ); delete[] cs;#ifdef QGISDEBUG std::cerr << "SQL: " << db_get_string(&dbstr) << std::endl;#endif int ret = db_execute_immediate (driver, &dbstr); if ( ret != DB_OK) { std::cerr << "Error: " << db_get_error_msg() << std::endl; error->setLatin1( db_get_error_msg() ); } db_close_database_shutdown_driver ( driver ); db_free_string(&dbstr); return error;}int QgsGrassProvider::numDbLinks ( void ){#ifdef QGISDEBUG std::cerr << "QgsGrassProvider::numDbLinks()" << std::endl;#endif return ( Vect_get_num_dblinks(mMap) );}int QgsGrassProvider::dbLinkField ( int link ){#ifdef QGISDEBUG std::cerr << "QgsGrassProvider::dbLinkField()" << std::endl;#endif struct field_info *fi = Vect_get_dblink ( mMap, link ); if ( fi == NULL ) return 0; return ( fi->number );}QString *QgsGrassProvider::executeSql ( int field, const QString &sql ){#ifdef QGISDEBUG std::cerr << "QgsGrassProvider::executeSql field = " << field << std::endl;#endif QString *error = new QString(); struct field_info *fi = Vect_get_field( mMap, field); // should work also with field = 0 // Read attributes if ( fi == NULL ) {#ifdef QGISDEBUG std::cerr << "No field info -> no attributes" << std::endl;#endif error->setLatin1( "Cannot get field info" ); return error; }#ifdef QGISDEBUG std::cerr << "Field info found -> open database" << std::endl;#endif QgsGrass::setMapset ( mGisdbase, mLocation, mMapset ); dbDriver *driver = db_start_driver_open_database ( fi->driver, fi->database ); if ( driver == NULL ) { std::cerr << "Cannot open database " << fi->database << " by driver " << fi->driver << std::endl; error->setAscii("Cannot open database"); return error; }#ifdef QGISDEBUG std::cerr << "Database opened" << std::endl;#endif dbString dbstr; db_init_string (&dbstr); db_set_string (&dbstr, (char *)sql.latin1());#ifdef QGISDEBUG std::cerr << "SQL: " << db_get_string(&dbstr) << std::endl;#endif int ret = db_execute_immediate (driver, &dbstr); if ( ret != DB_OK) { std::cerr << "Error: " << db_get_error_msg() << std::endl; error->setLatin1( db_get_error_msg() ); } db_close_database_shutdown_driver ( driver ); db_free_string(&dbstr); return error;}QString *QgsGrassProvider::createTable ( int field, const QString &key, const QString &columns ){#ifdef QGISDEBUG std::cerr << "QgsGrassProvider::createTable() field = " << field << std::endl;#endif QString *error = new QString(); struct field_info *fi = Vect_get_field( mMap, field); // should work also with field = 0 // Read attributes if ( fi != NULL ) {#ifdef QGISDEBUG std::cerr << "The table for this field already exists" << std::endl;#endif error->setLatin1( "The table for this field already exists" ); return error; }#ifdef QGISDEBUG std::cerr << "Field info not found -> create new table" << std::endl;#endif // We must set mapset before Vect_default_field_info QgsGrass::setMapset ( mGisdbase, mLocation, mMapset ); int nLinks = Vect_get_num_dblinks( mMap ); if ( nLinks == 0 ) { fi = Vect_default_field_info ( mMap, field, NULL, GV_1TABLE ); } else { fi = Vect_default_field_info ( mMap, field, NULL, GV_MTABLE ); } dbDriver *driver = db_start_driver_open_database ( fi->driver, fi->database ); if ( driver == NULL ) { std::cerr << "Cannot open database " << fi->database << " by driver " << fi->driver << std::endl; error->setAscii("Cannot open database"); return error; }#ifdef QGISDEBUG std::cerr << "Database opened -> create table" << std::endl;#endif dbString dbstr; db_init_string (&dbstr); QString query; query.sprintf("create table %s ( %s )", fi->table, columns.latin1() ); db_set_string (&dbstr, (char *)query.latin1());#ifdef QGISDEBUG std::cerr << "SQL: " << db_get_string(&dbstr) << std::endl;#endif int ret = db_execute_immediate (driver, &dbstr); if ( ret != DB_OK) { std::cerr << "Error: " << db_get_error_msg() << std::endl; error->setLatin1( db_get_error_msg() ); } db_close_database_shutdown_driver ( driver ); db_free_string(&dbstr); if ( !error->isEmpty() ) return error; ret = Vect_map_add_dblink ( mMap, field, NULL, fi->table, (char *)key.latin1(), fi->database, fi->driver); if ( ret == -1 ) { std::cerr << "Error: Cannot add dblink" << std::endl; error->setLatin1( "Cannot create link to the table. The table was created!" ); } return error;}QString *QgsGrassProvider::addColumn ( int field, const QString &column ){#ifdef QGISDEBUG std::cerr << "QgsGrassProvider::addColumn() field = " << field << std::endl;#endif QString *error = new QString(); struct field_info *fi = Vect_get_field( mMap, field); // should work also with field = 0 // Read attributes if ( fi == NULL ) {#ifdef QGISDEBUG std::cerr << "No field info" << std::endl;#endif error->setLatin1( "Cannot get field info" ); return error; } QString query; query.sprintf("alter table %s add column %s", fi->table, column.latin1() ); delete error; return executeSql ( field, query );}QString *QgsGrassProvider::insertAttributes ( int field, int cat ){#ifdef QGISDEBUG std::cerr << "QgsGrassProvider::insertAttributes() field = " << field << " cat = " << cat << std::endl;#endif QString *error = new QString(); struct field_info *fi = Vect_get_field( mMap, field); // should work also with field = 0 // Read attributes if ( fi == NULL ) {#ifdef QGISDEBUG std::cerr << "No field info -> no attributes" << std::endl;#endif error->setLatin1( "Cannot get field info" ); return error; } QString query; query.sprintf("insert into %s ( %s ) values ( %d )", fi->table, fi->key, cat ); delete error; return executeSql ( field, query );}QString *QgsGrassProvider::deleteAttributes ( int field, int cat ){#ifdef QGISDEBUG std::cerr << "QgsGrassProvider::deleteAttributes() field = " << field << " cat = " << cat << std::endl;#endif QString *error = new QString(); struct field_info *fi = Vect_get_field( mMap, field); // should work also with field = 0 // Read attributes if ( fi == NULL ) {#ifdef QGISDEBUG std::cerr << "No field info -> no attributes" << std::endl;#endif error->setLatin1( "Cannot get field info" ); return error; } QString query; query.sprintf("delete from %s where %s = %d", fi->table, fi->key, cat ); delete error; return executeSql ( field, query );}QString *QgsGrassProvider::isOrphan ( int field, int cat, int *orphan){#ifdef QGISDEBUG std::cerr << "QgsGrassProvider::isOrphan() field = " << field << " cat = " << cat << std::endl;#endif QString *error = new QString(); // Check first if another line with such cat exists int fieldIndex = Vect_cidx_get_field_index ( mMap, field ); if ( fieldIndex >= 0 ) { int t, id; int ret = Vect_cidx_find_next ( mMap, fieldIndex, cat, GV_POINTS|GV_LINES, 0, &t, &id ); if ( ret >= 0 ) { // Category exists *orphan = false; return error; } } // Check if attribute exists struct field_info *fi = Vect_get_field( mMap, field); // should work also with field = 0 // Read attributes if ( fi == NULL ) {#ifdef QGISDEBUG std::cerr << "No field info -> no attributes" << std::endl;#endif *orphan = false; return error; }#ifdef QGISDEBUG std::cerr << "Field info found -> open database" << std::endl;#endif QgsGrass::setMapset ( mGisdbase, mLocation, mMapset ); dbDriver *driver = db_start_driver_open_database ( fi->driver, fi->database ); if ( driver == NULL ) { std::cerr << "Cannot open database " << fi->database << " by driver " << fi->driver << std::endl; error->setAscii("Cannot open database"); return error; }#ifdef QGISDEBUG std::cerr << "Database opened -> select record" << std::endl;#endif dbString dbstr; db_init_string (&dbstr); QString query; query.sprintf("select %s from %s where %s = %d", fi->key, fi->table, fi->key, cat ); db_set_string (&dbstr, (char *)query.latin1());#ifdef QGISDEBUG std::cerr << "SQL: " << db_get_string(&dbstr) << std::endl;#endif dbCursor cursor; if ( db_open_select_cursor(driver, &dbstr, &cursor, DB_SCROLL) != DB_OK ) { db_close_database_shutdown_driver ( driver ); error->setAscii("Cannot query database: " + query ); return error; } int nRecords = db_get_num_rows ( &cursor );#ifdef QGISDEBUG std::cerr << "Number of records: " << nRecords << std::endl;#endif if ( nRecords > 0 ) { *orphan = true; } db_close_database_shutdown_driver ( driver ); db_free_string(&dbstr); return error;}// -------------------------------------------------------------------------------int QgsGrassProvider::cidxGetNumFields( ) { return ( Vect_cidx_get_num_fields(mMap) );}int QgsGrassProvider::cidxGetFieldNumber( int idx ) { return ( Vect_cidx_get_field_number(mMap, idx) );}int QgsGrassProvider::cidxGetMaxCat( int idx ) { int ncats = Vect_cidx_get_num_cats_by_index ( mMap, idx); int cat, type, id; Vect_cidx_get_cat_by_index ( mMap, idx, ncats-1, &cat, &type, &id ); return ( cat );} QString QgsGrassProvider::name() const{ return GRASS_KEY;} // QgsGrassProvider::name()QString QgsGrassProvider::description() const{ return GRASS_DESCRIPTION;} // QgsGrassProvider::description()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -