vector<string> getObjects(TeTheme* theme, vector<string>& itens)
{
	vector<string> svec;
	if(!theme)
		return svec;

	TeDatabase* db = 0;
	if(theme->getProductId() == TeEXTERNALTHEME)
		db = static_cast<TeExternalTheme*>(theme)->getSourceDatabase();
	else if(theme->getProductId() == TeTHEME)
		db = static_cast<TeTheme*>(theme)->layer()->database();

	if(db == 0)
		return svec;

	TeDatabasePortal* portal = db->getPortal();
	string C = theme->collectionTable();
	string CA = theme->collectionAuxTable();

	string query = "SELECT " + C + ".c_object_id FROM " + C + " LEFT JOIN " + CA;
	query += " ON " + C + ".c_object_id = " + CA + ".object_id";
	query += " WHERE " + CA + ".unique_id IN ";

	set<string> idSet;
  
  vector< string >::iterator it_begin = itens.begin();
  vector< string >::iterator it_end = itens.end();
  
	vector<string> inVec = generateInClauses(it_begin, it_end, db, false);
	vector<string>::iterator it;
	for(it=inVec.begin(); it!=inVec.end(); ++it)
	{
		if((*it).empty() == false)
		{
			string sel = query + *it;
			if (portal->query(sel) == false)
			{
				delete portal;
				return svec;
			}
			while (portal->fetchRow())
				idSet.insert(portal->getData(0));
			portal->freeResult();
		}
	}
	delete portal;

	set<string>::iterator sit;
	for(sit=idSet.begin(); sit!=idSet.end(); ++sit)
		svec.push_back(*sit);
	return svec;
}
vector<string> getItems(TeTheme* theme, int sel)
{
	vector<string> svec;
	if(!theme)
		return svec;

	TeDatabase* db = 0;
	if(theme->getProductId() == TeEXTERNALTHEME)
		db = static_cast<TeExternalTheme*>(theme)->getSourceDatabase();
	else if(theme->getProductId() == TeTHEME)
		db = static_cast<TeTheme*>(theme)->layer()->database();

	if(db == 0)
		return svec;

	string C = theme->collectionTable();
	string CA = theme->collectionAuxTable();
	string input;

	if(sel == TeSelectedByPointing)
		input += " WHERE " + CA + ".grid_status = 1 OR " + CA + ".grid_status = 3";
	else if(sel == TeNotSelectedByPointing)
		input += " WHERE " + CA + ".grid_status = 0 OR " + CA + ".grid_status = 2";
	else if(sel == TeSelectedByQuery)
		input += " WHERE " + CA + ".grid_status = 2 OR " + CA + ".grid_status = 3";
	else if(sel == TeNotSelectedByQuery)
		input += " WHERE " + CA + ".grid_status = 0 OR " + CA + ".grid_status = 1";
	else if(sel == TeSelectedByPointingAndQuery)
		input += " WHERE " + CA + ".grid_status = 3";
	else if(sel == TeSelectedByPointingOrQuery)
		input += " WHERE " + CA + ".grid_status <> 0";
	else if(sel == TeGrouped)
		input += " WHERE " + C + ".c_legend_id <> 0";
	else if(sel == TeNotGrouped)
		input += " WHERE " + C + ".c_legend_id = 0";

	string query = "SELECT " + CA + ".unique_id FROM " + C + " LEFT JOIN " + CA;
	query += " ON " + C + ".c_object_id = " + CA + ".object_id" + input;

	TeDatabasePortal* portal = db->getPortal();
	if (portal->query(query) == false)
	{
		delete portal;
		return svec;
	}
	while (portal->fetchRow())
		svec.push_back(portal->getData(0));

	delete portal;
	return svec;
}
aRTconn::aRTconn(string user, string pass, unsigned port, string host, string dbms)
{
	PrintSilent("Trying to connect ... ");
	User = user;
	Password = pass;
	Port = port;
	Host = host;

	if     (dbms == "mysql")   { Type = aRTmySQL;    if(!port) Port=3306; }
	else if(dbms == "postgre") { Type = aRTpostgres; if(!port) Port=5432; }
	else if(dbms == "postgis") { Type = aRTpostgis;  if(!port) Port=5432; }
	//else error("Invalid database type: %s\n", dbms.c_str());

	TeDatabase* database = NewTeDatabase();
//	vector<string> db_names;

	bool Valid = database->connect(Host, User, Password,  "", Port);

	if (!Valid)
	{
		PrintSilentNo;
		string error_msg = database -> errorMessage();
		delete database;
		error(error_msg.c_str());
	}
    PrintSilentYes;

	string query = "SELECT VERSION()";

	TeDatabasePortal* portal = database->getPortal();

	portal->query(query);
    portal->fetchRow();

	PrintSilent("Connected to %s version %s\n", dbms.c_str(), portal->getData(0));

	delete database;
}
// Try to open an existent database
aRTcomponent* aRTconn::OpenDb(SEXP data)
{
	bool silent = Silent; // **

    string dbname = GET_STRING_ELEMENT(data, "dbname");
	bool update   = GET_BOOL_ELEMENT(data,   "update");

	PrintSilent("Connecting to database \'%s\' ... ", dbname.c_str());
	
	Silent = false; // **
	TeDatabase* database = NewTeDatabase();

	// ** things doesn't work fine if this line executes with Silent == true
	// ** strange... I've already tried to change the name of this variable.
    if (database -> connect(Host, User, Password, dbname, Port))
	{
		Silent = silent; // **
		PrintSilentYes;

		string DBversion;
	    TeDatabasePortal* portal = database->getPortal();
	    if(!portal)
	        return false;

	    string sql = " SELECT db_version FROM te_database ";
	    //The database does not have the te_database connection
	    if(!portal->query(sql))
	    {
	        DBversion = "";
	        delete portal;
	        return NULL;
	    }

	    if(!portal->fetchRow())
	    {
	        DBversion = "";
	        delete portal;
	        return NULL;
	    }

	    DBversion = portal->getData(0);

		PrintSilent("Connected to database version %s\n", DBversion.c_str());

		string version, error_msg;
		if( needUpdateDB(database, version) )
		{
			if(update)
			{
				PrintSilent("Updating database \'%s\' to version %s ... ", dbname.c_str(), TeDBVERSION.c_str());
				if( updateDBVersion(database, version, error_msg) )
					{ PrintSilentYes; }
				else
					error("Could not update the database version: %s\n", error_msg.c_str());
			}
			else warning("Database needs to be updated to version %s. Call this function again with update=TRUE, otherwise things may not work correctly\n", TeDBVERSION.c_str());
		}
	}
	else
	{
		Silent = silent; // **
		PrintSilentNo;
		error("Database \'%s\'does not exist.", dbname.c_str());
	}
	
	aRTdb* root = new aRTdb(database);
	return root;
}
SEXP aRTconn::GetPermissions(SEXP data)
{
    SEXP result;
    SEXP *each_column;
    SEXP colnames;
    SEXP rownames;
	string query;
	string user = GET_STRING_ELEMENT(data, "user"  );
	bool global = GET_BOOL_ELEMENT  (data, "global");

	TeDatabase* db = NewTeDatabase();

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

	TeDatabasePortal* portal = db->getPortal();

	if(global)
		query = "select Host,User,Password,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv from mysql.user";
	else
		query = "select Host,User,Db,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv from mysql.db";

	if(user != "")
	{
		query += " where user= \"";
		query += user;
		query += "\";";
	}
	else
	{
		query += ";";
	}

	portal->query(query);

    each_column = new SEXP[8];
    colnames    = PROTECT(allocVector( STRSXP, 8 ));
    result      = PROTECT(allocVector( VECSXP, 8 ));
    rownames    = PROTECT(allocVector( STRSXP, portal->numRows() ));

	for(int i = 0; i < 8; i++)
	    each_column[i] = PROTECT(allocVector( STRSXP,  portal->numRows() ));

    SET_STRING_ELT(colnames, 0, mkChar("host"    ));
    SET_STRING_ELT(colnames, 1, mkChar("user"    ));
    SET_STRING_ELT(colnames, 2, mkChar(global? "password": "******"));
	SET_STRING_ELT(colnames, 3, mkChar("select"  ));
    SET_STRING_ELT(colnames, 4, mkChar("insert"  ));
    SET_STRING_ELT(colnames, 5, mkChar("update"  ));
    SET_STRING_ELT(colnames, 6, mkChar("delete"  ));
    SET_STRING_ELT(colnames, 7, mkChar("create"  ));

    for(int i = 0; i != portal->numRows(); i++)
    {
		portal->fetchRow();
        
		string host = portal->getData(0);

		if(host == "%") host = "<any>";
		SET_STRING_ELT( each_column[0], i, mkChar(host.c_str()) );
		
		// user
        SET_STRING_ELT( each_column[1], i, mkChar(portal->getData(1)) );

		if(global)
		{
			string password = portal->getData(2);
			password = password == ""? "No" : "Yes";
			SET_STRING_ELT( each_column[2], i, mkChar(password.c_str()) );
		}
		else
		{
			string db = portal->getData(2);
			SET_STRING_ELT( each_column[2], i, mkChar(db.c_str()) );
		}

		for(unsigned j = 3; j != 8; j++)
		{
			string value = portal->getData(j);
			if(value == "Y") value = "Yes";
			if(value == "N") value = "No";

        	SET_STRING_ELT( each_column[j], i, mkChar(value.c_str()) );
		}

        stringstream str;
        str << i+1; // rownames must start from 1
        SET_STRING_ELT(rownames, i, mkChar(str.str().c_str()));
    }

    setAttrib(result, R_NamesSymbol, colnames);

	for(unsigned j = 0; j != 8; j++)
    	SET_VECTOR_ELT(result, j, each_column[j]);

    result = AsDataFrame(result, rownames);
    UNPROTECT(11);
    delete[] each_column;
	delete db;

    return result;
}