void
fillCoverageMetadataTable(TeLayer* layer, std::string& metadataTableName, const std::string& coverageId, std::vector<TeCoverageDimension>& dimensions)
{
    TeDatabase* db = layer->database();
    if (!db->tableExist(metadataTableName))
    {   
        createCoverageMetadataTable(layer, metadataTableName);
    }

    for (std::vector<TeCoverageDimension>::iterator it = dimensions.begin(); it != dimensions.end(); it++)
    {
        const std::string& coverageIdStr = coverageId;
        const std::string dimensionIdStr = Te2String(it->dimension_id);
        const std::string dataTypeStr = Te2String(static_cast<TeDataType>(it->type));
        const std::string& nameStr = it->name;

        std::string sqlInsert = "INSERT INTO " + metadataTableName + " (coverage_id, dimension_id, data_type, name) VALUES ('" + coverageIdStr + "', '" + dimensionIdStr + "', '" + dataTypeStr + "', '" + nameStr + "')";

        if (!db->execute(sqlInsert))
        {
            std::string errorMsg = "Couldn't insert values to metadata table '" + metadataTableName + "'.";
            throw TeException(UNKNOWN_ERROR_TYPE, errorMsg, false);
        }
    }
}
SEXP aRTconn::DeleteDb(SEXP data)
{
	string databasename = GET_STRING_ELEMENT(data, "dbname");

	// "checking ...": R code already does.
	TeDatabase* database = NewTeDatabase();

	if( !database -> connect(Host, User, Password, "", Port))
	{
		PrintSilentNo;
		error("Could not connect\n");
	}
	
	PrintSilent("Deleting database \'%s\' ... ", databasename.c_str());
	
	stringstream stream;
	stream << "DROP DATABASE " << databasename << ";";
	string sql = StreamToChar(stream);

	if( !database->execute(sql) )
	{
		delete database;
		PrintSilentNo;
		error( database->errorMessage().c_str() );
	}
	
	delete database;
    PrintSilentYes;
	return RNULL;
}
SEXP aRTconn::AddPermission(SEXP data)  // only works in MySQL!
{
	string user      = GET_STRING_ELEMENT(data, "user"     );
	bool remote      = GET_BOOL_ELEMENT  (data, "remote"   );
	string host      = GET_STRING_ELEMENT(data, "host"     );
	string pass      = GET_STRING_ELEMENT(data, "pass"     );
	string database  = GET_STRING_ELEMENT(data, "database" );
	string privilege = GET_STRING_ELEMENT(data, "privilege");

	PrintSilent("Adding permissions to user \'%s\' ... ", user.c_str());
	TeDatabase* db = NewTeDatabase();

	if( !db -> connect(Host, User, Password, "", Port))
		error("Could not connect\n");

	stringstream stream;
	stream << "grant " << privilege << " ON " << database << ".* TO " << user;

	if(!remote && host == "") stream << "@localhost";
	else if(host != "")       stream << "@" << host;
	else                      stream << "@\'%\'";

	if(pass != "")
		stream << " IDENTIFIED BY \'" << pass << "\'";
	stream << ";";

	string sql = StreamToChar(stream);

//	cout << sql << endl;

	if( !db->execute(sql) )
	{
		string err = db->errorMessage();
		delete db;
		error( err.c_str() );
	}

	delete db;
    PrintSilentYes;
	return RNULL;
}
SEXP aRTconn::DropUser(SEXP data)
{
	string user      = GET_STRING_ELEMENT(data, "user"     );
	bool remote      = GET_BOOL_ELEMENT  (data, "remote"   );
	string host      = GET_STRING_ELEMENT(data, "host"     );

	PrintSilent("Dropping user \'%s\' ... ", user.c_str());
	TeDatabase* db = NewTeDatabase();

	if( !db -> connect(Host, User, Password, "", Port))
		error("Could not connect\n");

	stringstream stream;
	stream << "drop user " << user;

	if(!remote && host == "") stream << "@localhost";
	else if(host != "")       stream << "@" << host;
	else                      stream << "@\'%\'";

	stream << ";";

	string sql = StreamToChar(stream);

//	cout << sql << endl;

	if( !db->execute(sql) )
	{
		string err = db->errorMessage();
		delete db;
		error( err.c_str() );
	}

	delete db;
    PrintSilentYes;
	return RNULL;
}
bool TeCreateThemeFromTheme(TeTheme* inTheme, const string& newThemeName, int selObj, TeTheme* newTheme)
{
	// if no source theme or not a name for the new theme
	if (!inTheme || newThemeName.empty())
		return false;

	// if there no pointer theme was passed create a new instance
	if (!newTheme)
		newTheme = new TeTheme();

	// builds a valid theme name
	TeDatabase* curDb = inTheme->layer()->database();
	string validThemeName = newThemeName;
	int i=1;
	while (curDb->themeExist(validThemeName))
	{
		validThemeName = newThemeName + "_" + Te2String(i);
		i++;
	}

	// create new theme with the same definitions of the input theme
	newTheme->id(0);
	newTheme->name(validThemeName);
	newTheme->layer(inTheme->layer());
	newTheme->setAttTables(inTheme->attrTables());
	curDb->viewMap()[inTheme->view()]->add(newTheme);
	newTheme->visibleRep(inTheme->visibleRep());

	// save its definition in the database
	// creates collection and collection_aux table
	if (!newTheme->save())
	{
		delete newTheme;
		newTheme = 0;
    return false;
	}

	// if its a theme of raster data there's nothing else to be done
	if (inTheme->layer()->hasGeometry(TeRASTER) || inTheme->layer()->hasGeometry(TeRASTERFILE))
	{
		TeBox tbox = curDb->getThemeBox(newTheme);
		newTheme->setThemeBox(tbox);
		curDb->updateTheme(newTheme);
		return true;
	}

	// this SQL selects instances of objects according to input, so it uses te_collection_aux
	string inputInst;

	// this SQL selects objects according to input, so it uses te_collection
	string inputObj; 
	if(selObj == TeSelectedByPointing) // queried
	{
		inputObj = "(" + inTheme->collectionTable() + ".c_object_status = 2";
		inputObj += " OR " + inTheme->collectionTable() + ".c_object_status = 3)";
		inputInst = "(" + inTheme->collectionAuxTable() + ".grid_status = 2";
		inputInst += " OR " + inTheme->collectionAuxTable() + ".grid_status = 3)";
	}
	else if(selObj == 2) // pointed
	{
		inputObj = "(" + inTheme->collectionTable() + ".c_object_status = 1";
		inputObj += " OR " + inTheme->collectionTable() + ".c_object_status = 3)";
		inputInst = "(" + inTheme->collectionAuxTable() + ".grid_status = 1";
		inputInst += " OR " + inTheme->collectionAuxTable() + ".grid_status = 3)";
	}
	else if(selObj == 3) // not queried
	{
		inputObj = "(" + inTheme->collectionTable() + ".c_object_status <> 2";
		inputObj += " AND " + inTheme->collectionTable() + ".c_object_status <> 3)";
		inputInst = "(" + inTheme->collectionAuxTable() + ".grid_status <> 2";
		inputInst += " AND " + inTheme->collectionAuxTable() + ".grid_status <> 3)";
	}
	else if(selObj == 4) // not pointed
	{
		inputObj = "(" + inTheme->collectionTable() + ".c_object_status <> 1";
		inputObj += " AND " + inTheme->collectionTable() + ".c_object_status <> 3)";
		inputInst = "(" + inTheme->collectionAuxTable() + ".grid_status <> 1";
		inputInst += " AND " + inTheme->collectionAuxTable() + ".grid_status <> 3)";
	}
	else if(selObj == 5) // pointed and queried
	{
		inputObj = "(" + inTheme->collectionTable() + ".c_object_status = 3)";
		inputInst = "(" + inTheme->collectionAuxTable() + ".grid_status = 3)";
	}
	else if(selObj == 6) // pointed or queried
	{
		inputObj = "(" + inTheme->collectionTable() + ".c_object_status = 2";
		inputObj += " OR " + inTheme->collectionTable() + ".c_object_status = 1";
		inputObj += " OR " + inTheme->collectionTable() + ".c_object_status = 3)";
		inputInst = "(" + inTheme->collectionAuxTable() + ".grid_status = 2";
		inputInst += " OR " + inTheme->collectionAuxTable() + ".grid_status = 1";
		inputInst += " OR " + inTheme->collectionAuxTable() + ".grid_status = 3)";
	}

	// fills collection table from the selection requested

	string sql = "INSERT INTO " + newTheme->collectionTable() + " ( ";
	sql += " c_object_id, c_legend_id, label_x, label_y, c_legend_own, c_object_status ) ";
	sql += " SELECT * FROM " + inTheme->collectionTable();
	
	if(inputObj.empty() == false)
		sql += " WHERE " + inputObj;
	if (!curDb->execute(sql))
	{
		curDb->deleteTheme(newTheme->id());
		return false;
	}
	// sets theme objects settings to default
	sql = "UPDATE " + newTheme->collectionTable() + " SET c_legend_id = 0";
	if (!curDb->execute(sql))
	{
		curDb->deleteTheme(newTheme->id());
		return false;
	}
	sql = "UPDATE " + newTheme->collectionTable() + " SET c_object_status = 0";
	if (!curDb->execute(sql))
	{
		curDb->deleteTheme(newTheme->id());
		return false;
	}

	//fills collectin aux
	if(!newTheme->populateCollectionAux())
	{
		curDb->deleteTheme(newTheme->id());
		return false;
	}

	TeBox tbox = curDb->getThemeBox(newTheme);
	newTheme->setThemeBox(tbox);
	curDb->updateTheme(newTheme);

	return true;
}